Modifica vários arquivos em pastas diferentes com um comando?

2

Eu tenho um arquivo abc.txt na pasta /etc/zyz/ e também em algumas subpastas /etc/zyz-1/ /etc/zyz-2/

Como posso modificar todos esses arquivos com um comando echo , por exemplo (todos denominados abc.txt ) em todas as pastas que começam com /etc/zyz ? Em algumas máquinas existem apenas duas pastas, em outras existem 10 +

Exemplo de comandos que quero executar

echo 'New line data' >> abc.txt

abc.txt < /dev/null
    
por Teddy291 26.07.2015 / 22:53

3 respostas

2

Dada a seguinte árvore (vazia abc.txt):

.
├── zyz
│   └── abc.txt
├── zyz-1
│   └── abc.txt
└── zyz-2
    └── abc.txt

Você pode listar todos os arquivos abc com:

$ echo zyz*/abc.txt
  zyz-1/abc.txt zyz-2/abc.txt zyz/abc.txt

E você pode usar tee -a para acrescentar algum fluxo de entrada a todos esses arquivos ao mesmo tempo:

$ echo 'New line data' | tee -a zyz*/abc.txt
  New line data

Se você fizer isso duas vezes, cada abc.txt conterá duas linhas:

$ cat zyz/abc.txt
  New line data
  New line data
$ cat zyz-1/abc.txt
  New line data
  New line data
$ # ...

Para esvaziá-los, você pode fazer:

$ </dev/null tee zyz*/abc.txt

ou

$ : | tee zyz*/abc.txt

(Você não deve atingir o limite de ARG_MAX com apenas alguns arquivos com nomes abreviados, mas com um grande número de arquivos eu usaria find -exec no formulário + (consulte a página do manual).)

    
por 26.07.2015 / 23:16
2

Existem duas abordagens comuns para isso: find e shell globbing.

  1. find tem uma opção -exec que permite especificar uma ação a ser executada em cada um dos seus resultados. Ele disponibiliza cada um dos resultados do find como {} e você pode modificá-los como desejar. É um pouco mais complicado quando você quer dar argumentos (como echo foo > file ). Para isso, você precisa dizer ao exec do find para rodar um shell. Então, para echo foo em cada um dos arquivos encontrados, você executaria:

    find /etc/ -name abc.txt -path "/etc/zyz*" \
        -exec bash -c "echo 'New line data' >> {}" \;
    
  2. Shell globbing. Certas conchas (bash, zsh e ksh no topo da minha cabeça, mas tenho certeza de que existem mais) podem lidar com globos recursivos. No bash, isso é ativado por shopt globstar . Então, para echo New line data em cada um dos arquivos, você executaria:

    shopt globstar
    for f in /etc/zyz*/**/abc.txt; do echo "New line data" >> "$f"; done
    
por 26.07.2015 / 23:17
0

O arquivo não precisa ser apagado se você inserir uma linha depois, basta inserir a linha com ">".

@terdon algo com xargs ou paralelo também funcionaria: link

Estou bem com essa resposta de comentário que está sendo mesclada na sua:)

    
por 27.07.2015 / 00:50

Tags