Sort

使用自定義模式排序

  • January 5, 2018

有沒有辦法使用自定義模式輸出文件的內容?

例如,有一個myfile包含以下內容的文件:

a
d
b
c

..如何使用以下模式對其進行排序:首先列印以“b”開頭的行,然後列印以“d”開頭的行,然後按正常字母順序列印行,因此預期的輸出是:

b
d
a
c

您需要使用的不僅僅是sort命令。首先grepb行,然後是d行,然後對沒有bord的任何內容進行排序。

grep '^b' myfile > outfile
grep '^d' myfile >> outfile
grep -v '^b' myfile | grep -v '^d' | sort >> outfile
cat outfile

將導致:

b
d
a
c

這是假設行以“模式”開頭,b如果d這是整個模式​​或行內的某些內容,則可以省略插入符號 ( ^)

單行等效項是:

(grep '^b' myfile ; grep '^d' myfile ; grep -v '^b' myfile | grep -v '^d' | sort)

當您需要對超出 的能力的數據進行排序時sort,一種常見的方法是對數據進行預處理以添加排序鍵,然後排序,最後刪除額外的排序鍵。例如,在這裡,如果一行以 開頭,則添加 a,如果0一行以 開頭b,則添加a,否則添加 a 。1``d``2

sed -e 's/^b/0&/' -e t -e 's/^d/1&/' -e 't' -e 's/^/2/' |
sort |
sed 's/^.//'

請注意,這會對所有bd行進行排序。如果您希望這些行按原始順序排列,那麼最簡單的方法是拆分您想要保留 unsorted 的行。但是,您可以使用 - 將原始行轉換為排序鍵nl- 但這裡更複雜。\t(如果您的 sed 不理解該語法,請在整個過程中替換為文字製表符。)

nl -ba -nln |
sed 's/^[0-9]* *\t\([bd]\)/\1\t&/; t; s/^[0-9]* *\t/z\t0\t/' |
sort -k1,1 -k2,2n |
sed 's/^[^\t]*\t[^\t]*\t//'

或者,使用諸如 Perl、Python 或 Ruby 之類的語言,您可以輕鬆地指定自定義排序函式。

perl -e 'print sort {($b =~ /^[bd]/) - ($a =~ /^[bd]/) ||
                    $a cmp $b} <>'
python -c 'import sys; sys.stdout.write(sorted(sys.stdin.readlines(), key=lambda s: (0 if s[0]=="b" else 1 if s[0]=="d" else 2), s))'

或者如果您想按原始順序保留bandd行:

perl -e 'while (<>) {push @{/^b/ ? \@b : /^d/ ? \@d : \@other}, $_}
        print @b, @d, sort @other'
python -c 'import sys
b = []; d = []; other = []
for line in sys.stdin.readlines():
   if line[0]=="b": b += line
   elif line[0]=="d": d += line
   else: other += line
other.sort()
sys.stdout.writelines(b); sys.stdout.writelines(d); sys.stdout.writelines(other)'

引用自:https://unix.stackexchange.com/questions/75498