Como recursivamente percorro diretórios e nomeio um arquivo após o diretório?

0

O que eu estou tentando fazer é combinar todos os arquivos dentro de um subdiretório em um novo arquivo, e dar ao novo arquivo combinado o mesmo nome do subdiretório, e não tenho idéia de como fazer isso no Bash. Aqui está como eu me aproximei: Eu tenho um número de diretórios, cada um com um nome de arquivo único (com espaços!). Dentro de cada um desses diretórios, há vários arquivos nomeados numericamente, como:

Home/Unique name/1.pdf  
Home/Unique name/2.pdf  
Home/Unique name/3.pdf  
Home/Unique name/4.pdf  
....  
Home/Other Unique name/1.pdf  
Home/Other Unique name/2.pdf  
Home/Other Unique name/3.pdf  
Home/Other Unique name/4.pdf

O que eu gostaria de fazer é escrever um script bash (do diretório Home ) para:

  1. Entre em cada diretório exclusivo e execute um comando em cada um dos arquivos desse diretório (no meu caso, copie-os para um diretório diferente).
  2. Escrevi então um script diferente script.sh que executará outro comando (nesse caso, combine todos os PDFs em um único arquivo, temp.pdf ). Em seguida, gostaria de renomear o arquivo temp.pdf após o diretório Unique name.pdf (com espaços).
  3. Eu terei que seguir este processo para vários subdiretórios.

Eu tentei uma solução com um número de loops for, while loops e usando o comando find, mas não estou confortável o suficiente com o bash para depurar confortavelmente ou usar essas variáveis com qualquer grau de confiança. Eu também estou certo de que existe uma maneira mais eficiente de fazer o que estou fazendo, mas eu tenho bootstrapped o script juntos ao longo de um período de tempo.

    
por Marc 30.05.2013 / 13:07

2 respostas

1

A maneira POSIX é usar print . -type d ... | while read f; do , mas a menos que você esteja obcecado com 100% de portabilidade, eu não me incomodaria com isso. Se você tem bash 4+ e pdfunite (instalado por padrão no meu Ubuntu 13.04), você pode fazer isso em duas linhas:

shopt -s globstar
for f in ./**/; do pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Observe que shopt -s globstar precisa estar em uma linha separada para o restante. Com o globstar ativado, ** se expande para todos os arquivos e diretórios no diretório atual, recursivamente. Como os arquivos não podem conter / em seus nomes, **/ será expandido apenas para os diretórios. Eu uso ./**/ no caso improvável de que seus diretórios comecem com um hífen ( - ), pois isso pode causar problemas, pois muitos programas tratam qualquer coisa que comece com - como uma opção.

Conforme escrito, isso não copiará os PDFs para outro diretório, mas isso é muito fácil de adicionar:

for f in ./**/; do cp "$f"/*.pdf /target/dir/; pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Se você quiser usar seu próprio script personalizado de combinação de PDF, simplesmente altere a linha para se adequar - mas lembre-se de que a essência do script de shell é unir comandos pré-existentes.

Aqui está uma versão um pouco mais portátil:

print . -type d -print0 | while read -d $'
shopt -s globstar
for f in ./**/; do pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done
' f; do pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf" done
    
por 30.05.2013 / 14:11
0
  1. Crie for loop com find /home/ -type f -name "*.pdf" como variável
  2. Copie os arquivos para onde você precisa deles, tire $ VARIABLE e processe-os por meio do sed / awk para remover "/".

Poste seu script e podemos ajudá-lo a melhorá-lo.

Você sempre pode executar scripts com bash -x para depurá-los ou pode definir !#/bin/bash -x para sempre executar no modo de depuração (detalhado).

    
por 30.05.2013 / 13:47

Tags