Processe cada linha do arquivo de texto e exclua os arquivos relacionados do disco

2

Eu usei o comando find para encontrar vários arquivos e pastas e enviá-los para um arquivo de texto da seguinte forma:

nohup find /oradba -name '*soapr*' 2>/dev/null >find_soapr_db40.txt &

Então, em vez de exibir meus resultados na tela, enviei-os para o arquivo. Normalmente, eu poderia apenas acrescentar "-exec rm -rf {} \" ao final do meu comando find para encontrar arquivos relacionados e apagá-los ao mesmo tempo.

find / -name '*soatst*' 2>/dev/null -exec rm -rf {} \;

Mas como posso executar um comando para processar cada linha do arquivo .txt e excluir os arquivos que eles estão referenciando do disco?

O arquivo de texto contém itens como os seguintes:

/oradba/app/oracle/admin/soaprod2
/oradba/app/oracle/admin/soaprd2
/oradba/app/oracle/product/10.2.0.5/db_aprpsu/dbs/initsoaprd2.ora
/oradba/app/oracle/product/10.2.0.5/db_aprpsu/dbs/hc_soaprd2.dat
/oradba/app/oracle/product/10.2.0.5/db_aprpsu/dbs/alert_soaprd2.log
/oradba/app/oracle/product/10.2.0.5/db_aprpsu/dbs/spfilesoaprd2.ora
    
por etho201 17.01.2014 / 04:15

2 respostas

2

Perigo: é perfeitamente legal que os caminhos Unix contenham novas linhas. Se algum dos seus caminhos contiver novas linhas, isso é potencialmente perigoso. Considere usar find para separar os nomes dos arquivos usando a opção -print0 do GNU xargs e, em seguida, processando-os usando a opção GNU -0 ' rm .

Você pode usar o seguinte:

files=()

while IFS= read -r file; do
    files+=( "$file" )
done < ind_soapr_db40.txt

rm -r -- "${files[@]}"

Você poderia chamar for cada vez diretamente no loop rm , mas isso seria mais lento do que preencher a lista de arquivos e processá-los em uma invocação de mapfile .

Se você tem bash4 +, você pode usar %code% :

mapfile -t files < ind_soapr_db40.txt
rm -r -- "${files[@]}"
    
por 17.01.2014 / 04:20
0

Este one-liner Perl deve funcionar mesmo se seus nomes de arquivo tiverem novas linhas:

perl -000ne 'unlink (/(.+?\/[^\/]+)\n/sg);' list 

Para excluir diretórios e seus conteúdos de maneira recursiva, tente o seguinte:

perl -000ne 'use File::Path; rmtree (/(.+?\/[^\/]+)\n/sg);' list 

Explicação

  • -000 : ativa o modo de parágrafo, lê o arquivo inteiro de uma só vez.
  • -ne : leia o arquivo fornecido como argumento ( -n ) e execute o script passado por -e .

  • /(.+?\/[^\/]+)\n/sg : procure por qualquer caractere, seguido por um / e, em seguida, quantos caracteres não forem% de/ (incluindo novas linhas graças ao s modifier ) até a próxima nova linha. Como os nomes dos arquivos não podem conter / , isso deve selecionar o caminho inteiro e separar a ea

  • Transmita as correspondências (nomes de arquivo) retornadas pela expressão regular acima para unlink() excluí-los.

por 17.01.2014 / 05:43