В оболочке (bash) Как я могу выполнить более одной команды в конвейере? - PullRequest
4 голосов
/ 03 августа 2010

Я пытаюсь передать вывод команды awk сразу через несколько команд в оболочке Bash, следуя моим знаниям, я придумываю следующее:

awk '$13 ~ /type/ {print $15}' filename.txt | (wc -l || sort -u)

Я хочу получить результаткоманды awk для подсчета и сортировки, как я могу это сделать?Даже если команда && не работает, она выполняет первую команду и затем завершается.Я предполагаю, что это мое знание bash, которое терпит неудачу.

Заранее спасибо.

Ответы [ 5 ]

5 голосов
/ 03 августа 2010

Если вы хотите отправить вывод для двух разных команд в одной строке, вам нужно выполнить замену процесса.

Попробуйте это:

awk '$13 ~ /type/ {print $15}' filename.txt | tee >(wc -l >&2) | sort -u

Это выводит счетчик строк в stderr и отсортированный вывод в stdout. Если вам нужен счетчик строк в stdout, вы можете сделать это без >&2, но затем он будет передан в вызов сортировки и (скорее всего) отсортирован в начало вывода.

РЕДАКТИРОВАТЬ: исправлено описание того, что происходит на основе дальнейшего тестирования.

4 голосов
/ 03 августа 2010

в этом случае, вы считаете в awk, зачем нужны трубы?не усложняй

awk '$13 ~ /type/ {print $15;c++}END{print c} ' filename.txt | sort -u
1 голос
/ 04 августа 2010

Если размер выходных данных не слишком велик для размещения в памяти и вам не нужны команды wc и sort для параллельной работы из соображений производительности, вот относительно простое решение:

output=$(awk '$13 ~ /type/ {print $15}' filename.txt; echo a)
printf "%s" "${output%a}" | sort -u
printf "%s" "${output%a}" | wc -l

Эта сложность с дополнительным a заключается в том, что команда awk может напечатать несколько пустых строк в конце ввода, которые будут удалены конструкцией $(). Вы можете легко выбрать, какой из sort или wc должен отображаться первым.


Вот способ, который работает с любой оболочкой POSIX (ash, bash, ksh, zsh, ...), но только в системах с /dev/fd (который включает в себя сравнительно недавно Linux, * BSD и Solaris). Подобно аналогичной конструкции Уолтера с использованием более простого метода, доступного в bash, ksh93 и zsh , выходные данные wc и выходные данные sort могут быть смешаны.

{
  awk '$13 ~ /type/ {print $15}' filename.txt |
  tee /dev/fd3 |
  wc -l
} 3>&1 1>&3 | sort -u

Если вам обоим нужно иметь дело с промежуточным выводом, который не совсем удобно помещается в памяти и не хотят, чтобы вывод двух команд смешивался, я не думаю, что есть простой способ в оболочке POSIX, хотя это должно быть выполнимо с процессами ksh или zsh.

0 голосов
/ 03 августа 2010

Вы хотите использовать именованные каналы, созданные с помощью mkfifo в сочетании с tee.Пример: http://www.softpanorama.org/Tools/tee.shtml

0 голосов
/ 03 августа 2010

Я думаю, что больший вопрос: чего вы ожидаете получить?

Если вы пытаетесь сделать две вещи, тогда сделайте две вещи:

awk '$13 ~ /type/ {print $15}' filename.txt > tempfile
wc -l < tempfile
sort -u < tempfile
rm tempfile
...