Grave a saída de um comando find dentro de um loop para um arquivo

3

Eu tenho um comando find aninhado em um loop e quero gravar a saída em um arquivo e poder vê-lo ao vivo também. Mas todas as abordagens que tentei até agora falharam em cumprir isso.

Meu comando while é este:

while read -r LINE; do find "$LINE" -name "*Bop*" ; done < /drives/d/dirs_to_search.txt

Quando executo o comando acima, posso ver a lista de subdiretórios correspondentes impressos na minha janela de terminal. Quero continuar vendo essa lista de correspondências , mas ao mesmo tempo, gravá-las em um arquivo .

E as abordagens que tentei até agora para gravar a saída de find em um arquivo chamado matched_subdirs :

while read -r LINE; do find "$LINE" -name "*Bop*" | tee /drives/d/matched_subdirs.txt ; done < /drives/d/dirs_to_search.txt

while read -r LINE; do find "$LINE" -name "*Bop*" ; done < /drives/d/dirs_to_search.txt | tee /drives/d/matched_subdirs.txt

while read -r LINE; do find "$LINE" -name "*Bop*" -print; done < /drives/d/dirs_to_search.txt | tee /drives/d/matched_subdirs.txt

while read -r LINE; do find "$LINE" -name "*Bop*" > /drives/d/matched_subdirs.txt ; done < /drives/d/dirs_to_search.txt

while read -r LINE; do find "$LINE" -name "*Bop*"; done < /drives/d/dirs_to_search.txt > /drives/d/matched_subdirs.txt
    
por vivoru 13.07.2018 / 13:33

1 resposta

2

Os comandos que você mostrou devem , como diz o terdon , trabalhe.

Uma alternativa que elimina tee :

rm -f /drives/d/matched_subdirs.txt
while IFS= read -r pathname; do
    find "$pathname" -name '*Bop*' -print \
        -exec sh -c 'printf "%s\n" "$@" >>matched' sh {} +
done <dirlist

Isso permitirá que find imprima os nomes de caminhos encontrados para você ver e, em seguida, use um script de shell incorporado para gravá-los no arquivo de resultados.

Estou um pouco preocupado com o que você pretende fazer com os nomes de caminho no arquivo de saída. Se você pretende usá-los para fazer um loop mais tarde, seria melhor fazer isso diretamente de find . Você teria problemas com nomes de arquivos estranhos contendo novas linhas incorporadas de outra forma.

Nos comentários você diz que pretende usar os nomes de caminho encontrados em um loop para executar rsync . Chamar rsync para cada nome de caminho seria muito lento, e seria melhor fazer isso com rsync diretamente:

while IFS= read -r pathname; do
    rsync -avR --include='*/' --include='*Bop*' --exclude='*' --prune-empty-dirs "$pathname" target
done <dirlist

Aqui, dirlist é um arquivo com seus diretórios.

Exemplo:

$ tree
.
|-- dirlist
'-- source
    |-- a
    |   |-- dir-1
    |   |   |-- somefile_Bop_here
    |   |   '-- someotherfile
    |   |-- dir-2
    |   |   |-- somefile_Bop_here
    |   |   '-- someotherfile
    |   '-- dir-3
    |       |-- somefile_Bop_here
    |       '-- someotherfile
    |-- b
    |   |-- dir-1
    |   |   |-- somefile_Bop_here
    |   |   '-- someotherfile
    |   |-- dir-2
    |   |   |-- somefile_Bop_here
    |   |   '-- someotherfile
    |   '-- dir-3
    |       |-- somefile_Bop_here
    |       '-- someotherfile
    '-- c
        |-- dir-1
        |   |-- somefile_Bop_here
        |   '-- someotherfile
        |-- dir-2
        |   |-- somefile_Bop_here
        |   '-- someotherfile
        '-- dir-3
            |-- somefile_Bop_here
            '-- someotherfile

13 directories, 19 files
$ cat dirlist
source/a
source/b/dir-2

(executando loop aqui)

$ tree target
target
'-- source
    |-- a
    |   |-- dir-1
    |   |   '-- somefile_Bop_here
    |   |-- dir-2
    |   |   '-- somefile_Bop_here
    |   '-- dir-3
    |       '-- somefile_Bop_here
    '-- b
        '-- dir-2
            '-- somefile_Bop_here

7 directories, 4 files

Eu escolhi usar -R ( --relative ). Sem isso, eu teria conseguido

target
|-- a
|   |-- dir-1
|   |   '-- somefile_Bop_here
|   |-- dir-2
|   |   '-- somefile_Bop_here
|   '-- dir-3
|       '-- somefile_Bop_here
'-- dir-2
    '-- somefile_Bop_here
    
por 13.07.2018 / 14:35