Учитывая список слов и их количество следующим образом:
2 you
1 polka
2 dress
3 are
4 world
Я хотел бы напишите 2 команды Bash по конвейеру, которые дадут мне:
самое длинное слово, начинающееся с буквы «a»
наиболее частое слово, которое начинается с «a».
Я думал сделать это с помощью sed
grep ^ a
, но я не знаю, как написать остальную часть конвейерной команды.
Для получения самого долгого слова мы можем использовать awk
length
функция. Тогда вид, тогда head
и cut
для получения правильной строки и поля.
awk '$2~/^a/ {print length($2), $2}' file | sort -k1 | head -1 | cut -d" " -f1
Для получения самого частого A-слова, sort
и 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
Принятие файла 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
, С другой стороны, почему обязательно передает по каналу? Это - абсурдное требование.
Вот решение без требования использования канала с помощью 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