使用自定义模式排序

使用自定义模式排序

有没有办法使用自定义模式输出文件内容?

例如,有一个myfile包含以下内容的文件:

a
d
b
c

..如何使用以下模式对其进行排序:首先打印以“b”开头的行,然后打印以“d”开头的行,然后按正常字母顺序打印行,因此预期输出为:

b
d
a
c

答案1

当需要对数据进行超出sort能力的排序时,常见的方法是对数据进行预处理,在前面添加排序键,然后进行排序,最后删除多余的排序键。例如,此处,0如果一行以 开头b,则添加 a,1如果一行以 开头d,则添加 a,2否则添加 a。

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

请注意,这会对所有bd行进行排序。如果您希望这些行按原始顺序排列,那么最简单的方法是拆分出您想要未排序的行。但是,您可以将原始行转换为排序键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))'

或者如果您想保留bd行的原始顺序:

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)'

答案2

您需要使用的不仅仅是命令sort。首先是grepb,然后是d行,然后对末尾没有b或的任何内容进行排序。d

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

将导致:

b
d
a
c

这是假设这些行以“模式”开头bd如果这是所有的行内的图案或其他内容,您可以省略插入符号 ( ^)

一行等效内容是:

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

答案3

解决这个问题的一种方法awk是:

sort myfile | awk '$0 ~ /^b/ || $0 ~ /^d/ {print} $0 !~ /^b/ && $0 !~ /^d/ { a[f++] = $0 } END { for (word = 0; word < f; word++) { print a[word] } }'

答案4

除了grep解决方案之外,如果有文件记录并且您想保留命令,您可以使用参数你打电话的地方grep。假设您有包含一些数据的文件(custom_sort.txt):

ccc
aaa
xxx
nnn

并且您想要搜索包含附加信息的排序 grep 文件(sorted-data.txt):

aaa info
bbb test
ccc warn
...
mmm test
nnn info
...
xxx warn

如果你简单地 grep ,你将收到以下输出:

aaa info
ccc warn
nnn info
xxx warn

要像原始文件中那样排序数据,您需要:

cat custom_sort.txt | xargs -l1 -I KEY grep KEY sorted-data.txt

输出将是:

ccc warn
xxx warn
aaa info
nnn info

相关内容