Я должен отсортировать все слова из файла, данного как параметр в сценарии оболочки. Вот острота:
tr [:space:] '\n' <$1 | sort -nrk2,2 | uniq -c |sed 's/^ \+//g'
В основном, если у меня есть что-то вроде этого в моем файле:
bla bla bla bla hu hu hu
Это произведет
4 bla
3 hu
Я хочу, чтобы они были чем-то как
bla 4
hu 3
Вы могли заменить Ваш sed
команда с простым awk
команда, которая подкачивает полевой порядок
... | awk '{print $2,$1}'
Существуют многие, много способов сделать это. Steeldriver уже дал Вам классика awk
подход. Вот некоторый другой выбор:
Использовать sed
получать две группы непробела (\S
) символы и затем передвигают их:
... | sed -E 's/\s*(\S+)\s+(\S+)/\2 \1/'
Использовать perl
. -a
переключатель заставляет его работать как awk
. Это автоматически разделит каждую входную строку на пробеле и сохранит каждое поле как элемент массива @F
. Поэтому 1-е поле будет $F[0]
, второе $F[1]
и т.д.:
... | perl -lane 'print "$F[1] $F[0]"'
Используйте Perl для всего этого:
perl -lane '$k{$_}++ for @F; }{ print "$_ $k{$_}" for keys(%k)' "$1"
Здесь, perl
читает входной файл линию за линией и применяет сценарий к каждой строке. $k{$_}++ for @F
сохраняет каждое слово (каждое поле от @F
) как ключ в хеше %k
и увеличивает присваиваемое значение к одному каждому разу, когда слово замечено. Затем после того, как файл был обработан (это что }{
средства), это распечатает слово ($_
) и количество раз это было замечено ($k{$_}
) для каждого ключа, сохраненного в хеше.
Использовать awk
для всего этого:
awk '{for(i=1;i<=NF;i++){a[$i]++}}END{for(i in a){print i,a[i]}}' "$1"
Первое for
цикл iretares по каждому полю и добавляет то к значению, связанному с тем полем в массиве a
. Затем в конце файла это циклично выполняется по каждому элементу в a
и печатает элемент (слово) и присваиваемое значение (количество раз, слово было замечено).
Используйте оболочку со своим исходным конвейером:
... | while read a b; do echo "$b $a"; done