Как работают каналы внутри awk (сортировка с сохранением заголовка)

Следующая команда выводит заголовок файла и сортирует записи после заголовка. Но как это работает? Кто-нибудь может объяснить эту команду?

awk 'NR == 1; NR > 1 {print $0 | "sort -k3"}'
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
220
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Не могли бы вы пройти следующие один раз (только для пояснений). Чтобы узнать больше о 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.
}'

после NR == 1 нет {print}, печатает ли запись по умолчанию

Vipul Bajaj 11.12.2020 09:24

@VipulBajaj, да awk работает по методу condition, затем action, поскольку здесь НЕ упоминается ДЕЙСТВИЕ, поэтому по умолчанию будет печататься текущая строка, ура.

RavinderSingh13 11.12.2020 09:25

большое спасибо за быстрое и понятное объяснение

Vipul Bajaj 11.12.2020 09:25

@VipulBajaj, добро пожаловать и счастливого обучения на SO.

RavinderSingh13 11.12.2020 09:26

Хорошее использование команды оболочки внутри awk

anubhava 11.12.2020 09:34

| — это одно из перенаправлений, поддерживаемых 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)

Связанные вопросы:

Другие вопросы по теме