Sort
使用自定義模式排序
有沒有辦法使用自定義模式輸出文件的內容?
例如,有一個
myfile
包含以下內容的文件:a d b c
..如何使用以下模式對其進行排序:首先列印以“b”開頭的行,然後列印以“d”開頭的行,然後按正常字母順序列印行,因此預期的輸出是:
b d a c
您需要使用的不僅僅是
sort
命令。首先grep
是b
行,然後是d
行,然後對沒有b
ord
的任何內容進行排序。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/^.//'
請注意,這會對所有
b
和d
行進行排序。如果您希望這些行按原始順序排列,那麼最簡單的方法是拆分您想要保留 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))'
或者如果您想按原始順序保留
b
andd
行: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)'