Это такое перенаправление "|>" Просто ошибка или это что-то значит?

$ awk '/Bond/{c++; print "There is a match on line " NR} END{print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt
There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt

Как это работает

awk неявно перебирает все входные строки.

  • /Bond/{c++; print "There is a match on line " NR}

    Для строк, соответствующих регексу Bond, счетчик c увеличивается и выводится сообщение, показывающее, в какой строке находится совпадение. В awk количество прочитанных на данный момент строк равно NR.

  • END{print "\"Bond\" появился " c " раз в файле " FILENAME}

    После чтения последней строки выводится сообщение с общим количеством совпадений.

Многострочная версия

Для тех, кто любит, чтобы код располагался на многих строках:

awk '

/Bond/{
    c++
    print "There is a match on line " NR
}

END{
    print "\"Bond\" appeared " c " times in the file " FILENAME
}
' bond.txt

Отображение содержимого файла перед сводкой файла

Этот подход читает файл дважды. В первый раз выводится версия файла, отформатированная с номерами строк. Во второй раз выводится итоговый вывод:

$ awk 'FNR==NR{printf("%5d) %s\n", NR,$0);next} /Bond/{c++; print "There is a match on line " FNR} END{print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt{,}
    1) Secret agent Bond had been warned not to tangle with Goldfinger.
    2) But the super-criminal's latest obsession was too strong, too dangerous.
    3) He had to be stopped.
    4) Goldfinger was determined to take possession of half the supply of
    5) mined gold in the world--to rob Fort Knox!
    6) For this incredible venture he had enlisted the aid of the top
    7) criminals in the U.S.A, including a bevy of beautiful thieves from the
    8) Bronx. And it would take all of Bond's unique talents to make it fail--
    9) as fail it must.
There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt

Приведенный выше вариант отличается от первого двумя особенностями. Во-первых, в командной строке файл указан дважды как bond.txt bond.txt или, используя трюк bash расширение скобок, как bond.txt{,}.

Во-вторых, мы добавили команду:

FNR==NR{printf("%5d) %s\n", NR,$0);next}

Эта команда выполняется только если FNR==NR, где NR - общее количество прочитанных строк, а FNR - количество строк, прочитанных из текущего файла. Таким образом, когда FNR==NR, мы читаем файл в первый раз. Затем мы printf форматируем вывод и переходим к следующей строке, пропуская остальные команды сценария.

Альтернатива

В этом варианте мы читаем файл только один раз, печатая отформатированную версию и сохраняя итоговую информацию для печати в конце:

$ awk '{printf("%5d) %s\n", NR,$0)} /Bond/{c++; s=s ORS "There is a match on line " FNR} END{print s; print "\"Bond\" appeared " c " times in the file " FILENAME}' bond.txt
    1) Secret agent Bond had been warned not to tangle with Goldfinger.
    2) But the super-criminal's latest obsession was too strong, too dangerous.
    3) He had to be stopped.
    4) Goldfinger was determined to take possession of half the supply of
    5) mined gold in the world--to rob Fort Knox!
    6) For this incredible venture he had enlisted the aid of the top
    7) criminals in the U.S.A, including a bevy of beautiful thieves from the
    8) Bronx. And it would take all of Bond's unique talents to make it fail--
    9) as fail it must.

There is a match on line 1
There is a match on line 8
"Bond" appeared 2 times in the file bond.txt
9
25.09.2018, 11:20
2 ответа

Похоже, что это просто конвейер, вторая часть которого представляет собой пустую команду, содержащую только перенаправление. Запись в виде date | >fileможет упростить интерпретацию. Пустая команда ничего не делает, кроме как обрабатывает перенаправление, создавая файл.

date >| file, с другой стороны, будет действовать как переопределение параметра оболочки noclobber, который предотвращает перезапись существующих файлов обычным >.

$ touch foo; set -o noclobber
$ date > foo
bash: foo: cannot overwrite existing file
$ date >| foo       # works
18
27.01.2020, 20:05

Да, это не приведет к ошибке, потому что для bash > fileозначает перенаправление в файл с именем file. Поскольку в вашем случае нечего перенаправлять в файл, bash просто создаст имя файла file, в котором ничего нет.

[bd@centos-6.5 my-tests]$ date | > my_file
[bd@centos-6.5 my-tests]$ cat my_file
[bd@centos-6.5 my-tests]$ 
2
27.01.2020, 20:05

Теги

Похожие вопросы