É possível usar gawk
a -i inplace
opção e também imprimir coisas stdout
?
Por exemplo, se eu quiser atualizar um arquivo e se houver alguma alteração, imprima o nome do arquivo e as linhas alteradas para que stderr
eu possa fazer algo como
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;}' {} +
mas existe uma maneira de usar stdout
ou uma maneira mais limpa de imprimir esse bloco no fluxo alternativo?
find -type f -name 'myfiles' -exec grep -q 'pattern' {} \; -print -exec gawk -i inplace '{do_your_sub_and_print_to_dev/stderr_too}' {} \;
esse modo. Somente usará o awk para editar os arquivos que realmente contêm linhas que correspondem a esse padrão.grep
pode ser. Meu primeiro instinto é evitar ter que "processar" o arquivo duas vezes, mas não ficaria surpreso se, de fato, fosse mais rápido. Ele só vai para mostrar por que eu posso confiar em meu intestino em tarefas de perfil-print -exec gawk
não é mais executada) e 2) para na 1ª partida, a menos que a 1ª partida esteja no última linha, você ainda não está processando o arquivo inteiro duas vezes (é mais parecido com 1.X vezes). Além disso, segawk -i inplace
obras comosed -i
ele vai editar o arquivo no local de qualquer maneira - timestamps de atualização ou seja, inode etc mesmo se não havia nada para editar ...Respostas:
Você deve usar
/dev/stderr
ou em/dev/fd/2
vez de/proc/self/fd/2
.gawk
manipula/dev/fd/x
e/dev/stderr
por si só (independentemente de o sistema ter esses arquivos ou não).Quando você faz um:
gawk
faz awrite(2, "x\n")
, enquanto quando você faz:desde que não trate
/proc/self/fd/x
especialmente, faz um:Primeiro,
/proc/self/fd
é específico do Linux e, no Linux, eles são problemáticos. As duas versões acima não são equivalentes quando stderr é um arquivo normal ou outro buscável ou um soquete (para o qual o último falharia) (sem mencionar que desperdiça um descritor de arquivo).Dito isto, se você precisar gravar no stdout original, precisará salvá-lo em outro arquivo como:
gawk
redireciona o stdout com o local para o arquivo. É necessário porque, por exemplo, você deseja:para armazenar a
uname
saída nofile
.fonte
Apenas por diversão, uma abordagem alternativa usando apenas POSIX dispõe de
find
,sh
,grep
e (principalmente)ex
:(Todas as quebras de linha no comando acima são opcionais; podem ser condensadas em uma linha.)
Ou, sem dúvida mais legível:
:)
(Este comando não foi testado; as edições são bem-vindas se eu fizer alguma brincadeira.)
fonte