Не могли бы вы пройти следующие один раз (только для пояснений). Чтобы узнать больше о awk
, я предлагаю пройти хороший раздел обучения awk переполнения стека
awk ' ##Starting awk program from here.
NR == 1; ##Checking if line is first line then print it.
##awk works on method of condition then action since here is NO ACTION mentioned so by default printing of current line will happen
NR > 1{ ##If line is more than 1st line then do following.
print $0 | "sort -k3" ##It will be keep printing lines into memory and before printing it will sort them with their 3rd field.
}'
@VipulBajaj, да awk
работает по методу condition
, затем action
, поскольку здесь НЕ упоминается ДЕЙСТВИЕ, поэтому по умолчанию будет печататься текущая строка, ура.
большое спасибо за быстрое и понятное объяснение
@VipulBajaj, добро пожаловать и счастливого обучения на SO.
Хорошее использование команды оболочки внутри awk
|
— это одно из перенаправлений, поддерживаемых print и printf — в данном случае это канал для команды sort -k3
. Вы также можете использовать перенаправление для записи в файл с помощью >
:
awk 'NR == 1; NR > 1 {print $0 > "output.txt"}'
или добавить в файл с помощью >>
:
awk 'NR == 1; NR > 1 {print $0 >> "output.txt"}'
Первый запишет в файл output.txt
все строки, кроме первой, второй добавит в output.txt
все строки, кроме первой.
Понимание команды awk:
В целом программа awk построена из пар (pattern){action}
, в которых указано, что если pattern
возвращает ненулевое значение, выполняется action
. Один не обязательно, нужно писать оба. Если pattern
опущено, по умолчанию используется 1
, а если action
опущено, по умолчанию используется print $0
.
При просмотре рассматриваемой команды:
awk 'NR == 1; NR > 1 {print $0 | "sort -k3"}'
Мы замечаем, что есть две пары действие-шаблон. Первый читается как NR == 1
и указывает, что если мы обрабатываем первую запись (шаблон), то печатаем запись (действие по умолчанию). Второй немного сложнее. Схема ясна, а вот действие требует пояснений.
awk знает 4 оператора вывода, которые могут перенаправлять вывод. Один из них гласит expression | cmd
. По сути, это означает, что awk будет записывать выходные данные в поток, который передается в качестве входных данных для команды cmd
. Он будет продолжать записывать вывод в этот поток до тех пор, пока поток не будет явно закрыт с помощью оператора close(cmd)
или путем простого завершения работы awk.
В случае OP действие читается как { print $0 | "sort -k3" }
, что означает, что оно будет печатать все записи $0
в поток, который используется в качестве ввода команды оболочки sort -k3
. Только когда программа завершит работу, sort
напишет свой вывод.
Резюме: команда OP напечатает первую строку файла и отсортирует последовательные строки в соответствии с третьим столбцом.
Альтернативные решения:
Используя GNU awk, лучше сделать:
awk '(FNR==1);{a[$3]=$0}
END{PROCINFO["sorted_in"] = "@ind_str_asc"
for(i in a) print a[i]
}' file
Используя чистый шелл, лучше сделать:
cat file | (read -r; printf "%s\n" "$REPLY"; sort -k3)
Связанные вопросы:
после NR == 1 нет {print}, печатает ли запись по умолчанию