A menos que você saiba o que o comando sed
está fazendo, você deseja executar um sed
por arquivo de entrada.
Você pode fazer isso com um loop for
(se seu shell for compatível com globalização recursiva), por exemplo, zsh
, ksh93
, yash
, bash
( tcsh
e fish
também, mas a sintaxe do loop é diferente lá).
shopt -s globstar # bash
#set -o globstar # ksh93
#set -o extended-glob # yash
for f in **/file.txt; do [ -f "$f" ] && sed 'cmd' "$f"; done
ou (como apontado por outras pessoas) com find
:
find . -type f -name 'file.txt' -exec sed 'cmd' {} \;
Agora, alguém pode se perguntar: por que não "otimizar" isso e usar find
s -exec
com +
ou zsh
-ism como:
sed 'cmd' **/file.txt(.)
Claro, isso seria mais eficiente, pois invocam sed
com vários operandos arquivo , mas isso pode muito bem o problema:
Para simplificar, imagine que você está tentando imprimir apenas a primeira linha de cada arquivo usando sed
command 1q
1 (sem editar o arquivo in-place 2 , talvez para redirecionar a saída combinada para outro arquivo ou apenas para inspecioná-lo) para que você possa executar
find . -name 'file.txt' -exec sed '1q' {} +
ou
sed '1q' **/file.txt(.)
no entanto ambos falharão na entrega porque se múltiplos operandos de arquivo forem especificados, os arquivos nomeados serão lidos na ordem especificada e a concatenação será editada
e como resultado sed
somente imprimirá a 1ª linha de entrada não a 1ª linha de cada arquivo 3 .
Agora, gnu sed
tem a opção -s
:
-s, --separate
consider files as separate rather than as a single continuous long stream
que pode ser útil às vezes, mas neste caso específico ( 1q
), não ajudará.
1: se você não gosta de 1q
try $d
, que deve apagar a última linha de cada arquivo
2: você pode se safar com gnu sed
às vezes como -i
implica -s
, mas definitivamente não quando um dos comandos sed
é q
3: você pode argumentar que isso ocorre porque q
desiste - mas o mesmo aconteceria se você usasse sed -n '1p'
- eu usei apenas q
para enfatizar 2: