我想过滤具有以下格式的文件:
Name1|Name2|Name3
ACGRTIDKEBDIVNRDIVFDOCDDIC
Name4|Name5|Name6
AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
Name1|Name7|Name3
AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
输出
Name1|Name7|Name3
AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name1|Name2|Name3
ACGRTIDKEBDIVNRDIVFDOCDDIC
Name4|Name5|Name6
AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
我按照第一个名称对文件进行排序,并将第1行和第2行保持在一起;但我也希望只保留最长的第二行(这里是留置权1和2,删除第3行和第4行)。
我可以使用awk按名称排序:
awk '{if ((NR%1-2)==0) {line=sprintf("%-30s", $0)} else {print line ":" $0}}' file | sort -t '|' -k1 | tr ':' '\n' > newfile
我不知道如何按第二行的长度排序(仅保留)(使用sort -n)?
由于
答案 0 :(得分:1)
Perl解决方案:
#!/usr/bin/perl
use strict;
use warnings;
my %by_length;
my ($id, $l1);
while (<>) {
( sub { $by_length{$id} = {l1 => $l1, l2 => $_}
if length > length($by_length{$id}{l2} // "")
},
sub { $id = (split /\|/)[0]; $l1 = $_ }
)[$. % 2]->()
}
print @{ $by_length{$_} }{qw{ l1 l2 }} for sort keys %by_length;
哈希%by_length
在l2
子项中存储每个名称的最长行,以及l1
下的相应第一行。
答案 1 :(得分:1)
复杂 awk
+ sort
解决方案:
awk 'NR % 2 == 0{ sub(/\|/, " ", r); print length, r, $0 }{ r = $0 }' file \
| sort -k2,2 -k1,1nr | awk '{ print $2"|"$3 ORS $NF }'
输出:
Name1|Name7|Name3
AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name1|Name2|Name3
ACGRTIDKEBDIVNRDIVFDOCDDIC
Name4|Name5|Name6
AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
奖金解决方案(附加要求):
awk 'NR % 2 == 0{ sub(/\|/, " ", r); print length, r, $0 }{ r = $0 }' file \
| sort -k2,2 -k1,1nr | awk '!a[$2]++{ print $2"|"$3 ORS $NF }'
输出:
Name1|Name7|Name3
AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name4|Name5|Name6
AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
答案 2 :(得分:1)
以下是如何在不必将整个文件存储在内存中的情况下轻松便携地执行操作:
1)将每对线折叠成1并在前面添加要排序的键:
$ awk -F'|' 'NR%2{n=$1; h=$0; next} {print n, length(), h, $0}' file
Name1 28 Name1|Name2|Name3 ACGRTIDKEBDIVNRDIVFDOCDDIC
Name4 52 Name4|Name5|Name6 AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
Name1 37 Name1|Name7|Name3 AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
2)按照您喜欢的顺序对上述输出进行排序:
$ awk -F'|' 'NR%2{n=$1; h=$0; next} {print n, length(), h, $0}' file |
sort -k1,1 -k2,2nr
Name1 37 Name1|Name7|Name3 AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name1 28 Name1|Name2|Name3 ACGRTIDKEBDIVNRDIVFDOCDDIC
Name4 52 Name4|Name5|Name6 AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
3)保持每个主键值的第一次出现:
$ awk -F'|' 'NR%2{n=$1; h=$0; next} {print n, length(), h, $0}' file |
sort -k1,1 -k2,2nr |
awk '!seen[$1]++'
Name1 37 Name1|Name7|Name3 AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name4 52 Name4|Name5|Name6 AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
4)删除步骤1中添加的额外字段,重新分成2行分区,然后打印结果:
$ awk -F'|' 'NR%2{n=$1; h=$0; next} {print n, length(), h, $0}' file |
sort -k1,1 -k2,2nr |
awk '!seen[$1]++{print $3 ORS $4}'
Name1|Name7|Name3
AGRQHUOQGRINQJIOPQPJGREQPJIRPEQJIRPEQ
Name4|Name5|Name6
AFFHJORJOVFDANJFOONKFANIFNIPNIPNFIPNKFPDNBKFPNBKFP
如果空白字符不适合作为组合字段的分隔符,则只需选择一个不同的字符(例如制表符或控制字符或......)。