给出一个单词列表及其数量如下:
2 you
1 polka
2 dress
3 are
4 world
我想编写 2 个 Bash 管道命令,它们将给我:
这最长以字母“a”开头的单词
这最频繁以 'a' 开头的单词。
我本来想用它来做这件事sed
grep ^a
,但我不知道如何编写管道命令的其余部分。
答案1
为了得到最长的单词,我们可以使用awk
的length
函数。然后进行排序,然后head
和cut
得到正确的行和字段。
awk '$2~/^a/ {print length($2), $2}' file | sort -k1 | head -1 | cut -d" " -f1
为了得到最常见的 A 字,asort
和awk
:
sort -k1 file | awk '$2~/^a/ {print $2; exit}'
在现实生活中,我可能会避免过多地使用管道。我可能会在一个单独的 中完成每件事awk
。但很难说它们是否真的会执行得更快。awk
很灵活,但速度没那么快。
awk 'BEGIN{lc=0;lw=""} $2~/^a/ {l=length($2); if (l>lc){lc=l;lw=$2}} END{print lw}' file
awk 'BEGIN{fc=0;fw=""} $2~/^a/ {if ($1>fc){fc=$1;fw=$2}} END{print fw}' file
答案2
这是一个使用 AWK 且不需要使用管道的解决方案:
awk '$2~/^a/{if(length($2)>length(x))x=$2}END{print x}' in
awk '$2~/^a/{if($1>x[0]){x[0]=$1;x[1]=$2}}END{print x[1]}' in
使用 Perl:
perl -lane '$F[1]=~/^a/||next;if(length($F[1])>length($x)){$x=$F[1]};END{print($x)}' in
perl -lane '$F[1]=~/^a/||next;if($F[0]>$x[0]){$x[0]=$F[0];$x[1]=$F[1]};END{print($x[1])}' in
% cat in
2 you
1 polka
2 dress
3 are
4 world
1 abcd
4 abc
% awk '$2~/^a/{if(length($2)>length(x))x=$2}END{print x}' in
abcd
% awk '$2~/^a/{if($1>x[0]){x[0]=$1;x[1]=$2}}END{print x[1]}' in
abc
% perl -lane '$F[1]=~/^a/||next;if(length($F[1])>length($x)){$x=$F[1]};END{print($x)}' in
abcd
% perl -lane '$F[1]=~/^a/||next;if($F[0]>$x[0]){$x[0]=$F[0];$x[1]=$F[1]};END{print($x[1])}' in
abc
答案3
假设文件是foo
:
最长的单词
a
% awk '$2 ~ /^a/ {print length($2),$2}' foo | sort | tail -n1 3 are
最常用的词是
a
% awk '$2 ~ /^a/ {print $1,$2}' foo | sort | tail -n1 3 are
另一方面,为什么一定要管道?这是一个荒谬的要求。