Script Bash para localizar todas as pastas que contêm um arquivo específico e copiar um novo arquivo para essas pastas

1

Estou tentando escrever um script que percorra todas as subpastas de um diretório para procurar um arquivo específico e copie um novo arquivo para as pastas que contêm esse arquivo.

Isso é o que eu tenho até agora:

#!/bin/sh
dir=/Documents
find "$dir" -name Sample.doc -printf "%p\n" | sort -nr | while read -r i; do
  echo "$i"
  done

Isso funciona para listar todos os arquivos Sample.doc e suas pastas na pasta Documents .

No entanto, não consigo encontrar uma maneira de extrair o caminho dessas pastas para copiar o novo arquivo para elas.

Qualquer ajuda seria apreciada.

    
por Vard0 11.12.2014 / 10:03

4 respostas

0

O comando dirname remove o nome do arquivo do caminho completo

    
por 11.12.2014 / 12:09
0

Eu acho que você está quase lá. Você pode substituir %p por %h na expressão -printf :

%h : Leading directories of file's name (all but the last element). If the file name contains no slashes (since it is in the current directory) the %h specifier expands to ".".

para que o comando seja algo como:

find "$dir" -name Sample.doc -printf "%h\n" | sort -nr | while read -r i; do cp SomeFile "$i"; done

a propósito, por que a parte sort é necessária?

    
por 11.12.2014 / 12:23
0

Usar %h em vez disso %p já foi sugerido em outra resposta, mas gostaria de adicionar algumas melhorias para tornar seu código mais robusto. Se, por exemplo, um diretório correspondente contiver um caractere de nova linha em seu nome, você, no melhor dos casos, acabará perdendo os diretórios e obtendo algumas mensagens de erro de cp . Na pior das hipóteses, você pode substituir arquivos em qualquer lugar do sistema.

Então, tente fazer assim:

find "$dir" -name Sample.doc -printf "%h
find "$dir" -name Sample.doc -printf "%h%pre%" | xargs --null -L1 cp SomeFile
" | xargs --null -L1 cp SomeFile

O zero ACSII é garantido para nunca aparecer em qualquer nome de arquivo, então, ao contrário de \n , ele funciona como um separador confiável para passar os caminhos. --null diz a xargs para usar o cp Somefile como um delimitador de entrada. Em seguida, executará o comando fornecido ( %code% ) uma vez por item passado pelo canal, enquanto anexando o respectivo item como argumento adicional.

    
por 11.12.2014 / 18:33
0

No bash:

shopt -s nullglob globstar
for i in "$dir"/**/Sample.doc
do
    cp 'new file' "$(dirname "$i")"/
done

Em peixes:

for i in $dir/**Sample.doc
    cp 'new file' (dirname $i)/
end
    
por 22.12.2016 / 23:23