usando Find -exec para renomear um arquivo com o conteúdo grepped do arquivo

0

Estou tentando obter uma lista de arquivos com o find e, em seguida, uso o pdfgrep para obter uma string do arquivo e renomeie o arquivo com essa string.

Os comandos detalhados são:

find . -name "*PayrollSelfBill_42652301*" -exec pdfgrep {}  -o -e "42652301-.{10}"

o find recebe os arquivos que eu estou interessado, o pdfgrep na parte -exec puxa a string correta.

Eu quero o arquivo em {} para o resultado do pdfgrep.

Eu tentei criar variáveis (com $ () / backticks) e vários -execs, mas parece que não consigo fazer nada funcionar.

Alguém tem e solução elegante?

    
por mAndroid 13.07.2018 / 18:31

1 resposta

1

Para um único arquivo, $filename , você faria, se eu entendi corretamente, deseja fazer algo como

mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"

... assumindo $filename era o nome de um arquivo no diretório atual. Certo? Se não, o código abaixo também não estaria correto ...

Ok, vamos colocar isso em find com -execdir :

find . -type f -name "*PayrollSelfBill_42652301*" -execdir sh -c '
    filename=$1
    mv -i "$filename" "$( pdfgrep "$filename" -o -e "42652301-.{10}" )"' sh {} ';'

Isso localizaria os arquivos nos quais você está interessado e executaria o fragmento de script no mesmo diretório em que o arquivo foi encontrado (é assim que -execdir difere de -exec ). / p>

É possível que

find . -type f -name "*PayrollSelfBill_42652301*" \
    -execdir mv -i {} "$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

funcionaria também, na verdade, sem o shell filho adicionado ... agora que penso nisso. Mas eu me sentiria mais seguro chamando um shell filho, pois -execdir é uma opção não padrão em find .

Assumindo que $pathname é um dos arquivos encontrados, mas não é no diretório atual, o seguinte faria o mesmo para esse arquivo:

mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"

Aqui, ${pathname%/*} iria expandir para o diretório do arquivo encontrado (é o mesmo que $( dirname "$pathname" ) ).

Isso pode funcionar

find . -type f -name "*PayrollSelfBill_42652301*" \
    -exec  mv -i {} "$( dirname {} )/$( pdfgrep {} -o -e "42652301-.{10}" )" ';'

Mas podemos ser um pouco mais eficientes e usar -exec ... {} + para processar vários arquivos em lote:

find . -type f -name "*PayrollSelfBill_42652301*" -exec sh -c '
    for pathname do
        mv -i "$pathname" "${pathname%/*}/$( pdfgrep "$pathname" -o -e "42652301-.{10}" )"
    done' sh {} +

A diferença da solução -execdir acima é que apenas um (ou muito poucos) sh -c scripts seriam iniciados e dirname é substituído por uma substituição mais rápida, tornando-o potencialmente mais rápido do que a variação anterior isto.

Relacione-se com as duas variações nesta resposta:

por 13.07.2018 / 19:58

Tags