Можно ли использовать gawk
«s -i inplace
варианта , а также печатать вещи stdout
?
Например, если я хочу обновить файл, и если есть какие-либо изменения, напечатайте имя файла и измененные строки, чтобы stderr
я мог сделать что-то вроде
find -type f -name 'myfiles' -exec gawk -i inplace '{if(gsub(/pat/, "repl")) { print FILENAME > "/proc/self/fd/2" ; print > "/proc/self/fd/2"; } print;}' {} +
но есть ли способ использовать stdout
вместо этого или более чистый способ печати этого блока в альтернативный поток?
find -type f -name 'myfiles' -exec grep -q 'pattern' {} \; -print -exec gawk -i inplace '{do_your_sub_and_print_to_dev/stderr_too}' {} \;
, вы будете использовать awk только для редактирования файлов, которые на самом деле содержат строки, соответствующие этому шаблону.grep
может быть. Мой первый инстинкт - не обрабатывать файл дважды, но я не удивлюсь, если он действительно быстрее. Это просто показывает, почему я могу доверять своей интуиции в задачах профилирования-print -exec gawk
больше не выполняется) и 2) он остановится на первом совпадении, поэтому, если первое совпадение не будет В последней строке вы все еще не обрабатываете весь файл дважды (это больше похоже на 1X раз). Кроме того, если онgawk -i inplace
работает как-то,sed -i
он все равно будет редактировать файл на месте - т.е. обновлять метки времени, inode и т. Д., Даже если редактировать было нечего ...Ответы:
Вы должны использовать
/dev/stderr
или/dev/fd/2
вместо/proc/self/fd/2
.gawk
обрабатывает/dev/fd/x
и/dev/stderr
сам по себе (независимо от того, есть ли в системе эти файлы или нет).Когда вы делаете:
gawk
делаетwrite(2, "x\n")
, а когда вы делаете:так как он не обрабатывает
/proc/self/fd/x
специально, он делает:Во-первых,
/proc/self/fd
это специфично для Linux, а в Linux они проблематичны. Две вышеупомянутые версии не эквивалентны, когда stderr является обычным или другим доступным для поиска файлом или сокетом (для которого последний не сможет работать) (не говоря уже о том, что он использует файловый дескриптор).При этом, если вам нужно записать в исходный стандартный вывод, вам нужно сохранить его в другом файле, например:
gawk
перенаправляет стандартный вывод с файлом на место Это необходимо, потому что, например, вы хотите:сохранить
uname
вывод вfile
.источник
Просто для удовольствия, альтернативный подход , использующий только POSIX черты
find
,sh
,grep
и (самое главное)ex
:(Все разрывы строк в приведенной выше команде являются необязательными; они могут быть сжаты до одной строки.)
Или, возможно, более разборчиво:
:)
(Эта команда не проверена; изменения приветствуются, если я сделал какие-то глупости.)
источник