Eu tenho um arquivo de texto longo com uma lista de máscaras de arquivo que desejo excluir
Exemplo:
/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php
Eu preciso excluí-los. Tentei rm `cat 1.txt` e ele diz que a lista é muito longa.
Encontrei este comando, mas quando eu verifico as pastas da lista, algumas delas ainda têm arquivos.
xargs rm <1.txt
A chamada de rm manual remove os arquivos dessas pastas, portanto, não há problema com as permissões.
Respostas:
Isso não é muito eficiente, mas funcionará se você precisar de padrões glob (como em / var / www / *)
Se você não tiver nenhum padrão e tiver certeza de que seus caminhos no arquivo não contêm espaços em branco ou outras coisas estranhas, você pode usar xargs como:
fonte
Supondo que a lista de arquivos esteja no arquivo
1.txt
, faça:A
-r
opção causa recursão em qualquer diretório nomeado em1.txt
.Se algum arquivo for somente leitura, use a
-f
opção para forçar a exclusão:Seja cauteloso com informações de qualquer ferramenta que faça exclusões programáticas. Certifique -se de que os arquivos nomeados no arquivo de entrada sejam realmente excluídos. Seja especialmente cuidadoso com erros de digitação aparentemente simples. Por exemplo, se você inserir um espaço entre um arquivo e seu sufixo, aparecerá dois nomes de arquivo separados:
são na verdade dois arquivos separados:
file
e.txt
.Isso pode não parecer tão perigoso, mas se o erro de digitação for algo assim:
Então, em vez de apagar todos os arquivos que começam com
myoldfiles
, você vai acabar apagandomyoldfiles
e todos os não-dot-arquivos e diretórios no diretório atual. Provavelmente não é o que você queria.fonte
Usa isto:
Se precisar de expansão global, você pode omitir as citações
$file
:Mas esteja avisado que os nomes dos arquivos podem conter conteúdo "problemático" e eu usaria a versão não citada. Imagine este padrão no arquivo
Isso excluiria bastante do diretório atual! Eu o encorajaria a preparar a lista de exclusão de uma forma que os padrões glob não sejam mais necessários, e então usar aspas como no meu primeiro exemplo.
fonte
/My Dir With Spaces/
/Spaces and globs/*.txt
,--file-with-leading-dashes
e como um bônus é POSIX e funciona em GNU / Linux, MacOS e BSD.Você pode usar '\ n' para definir o caractere de nova linha como delimitador.
Tenha cuidado com o -rf porque ele pode excluir o que você não deseja se o 1.txt contiver caminhos com espaços. É por isso que o novo delimitador de linha é um pouco mais seguro.
Em sistemas BSD, você pode usar a opção -0 para usar caracteres de nova linha como delimitador como este:
fonte
xargs: illegal option -- d
-0
no OS X.xargs -I_ rm _
também funciona no OS X :) consulte stackoverflow.com/a/39335402/266309-d
), você pode primeiro converter novas linhas em nulos:tr '\n' '\0' < 1.txt | xargs -0 rm
Você pode usar este one-liner:
Que faz a expansão do shell, mas executa
rm
o número mínimo de vezes.fonte
-n <n>
argumento axargs
para reduzir o número de argumentos passados para cada rm, mas isso ainda não o protegerá de um único glob que exceda o limite.xargs -I{} sh -c 'rm {}' < 1.txt
deve fazer o que quiser. Tenha cuidado com este comando, pois uma entrada incorreta nesse arquivo pode causar muitos problemas.Esta resposta foi editada depois que @tdavies apontou que o original não fazia expansão de shell.
fonte
xargs -I{} sh -c 'rm {}' < 1.txt
Neste caso particular, devido aos perigos citados em outras respostas, eu
Edite, por exemplo, no Vim e
:%s/\s/\\\0/g
, escapando todos os caracteres de espaço com uma barra invertida.Então
:%s/^/rm -rf /
, antes do comando. Com-r
você não precisa se preocupar em ter diretórios listados após os arquivos neles contidos, e com-f
ele não reclamará por falta de arquivos ou entradas duplicadas.Execute todos os comandos:
$ source 1.txt
fonte
cat 1.txt | xargs rm -f | bash
Executar o comando fará o seguinte apenas para arquivos.cat 1.txt | xargs rm -rf | bash
Executar o comando fará o seguinte comportamento recursivo.fonte
Só para fornecer uma outra maneira, você também pode simplesmente usar o seguinte comando
fonte
Aqui está outro exemplo de loop. Este também contém uma 'instrução if' como um exemplo de verificação para ver se a entrada é um 'arquivo' (ou um 'diretório', por exemplo):
fonte
Aqui você pode usar um conjunto de pastas de deletelist.txt , evitando alguns padrões também
fonte
Isso permitirá que os nomes dos arquivos tenham espaços (exemplo reproduzível).
fonte
Caso alguém prefira
sed
e remova sem expansão curinga :Lembrete: use nomes de caminho absolutos no arquivo ou certifique-se de que está no diretório correto.
E para completar o mesmo com
awk
:A expansão do curinga funcionará se as aspas simples forem removidas, mas isso é perigoso caso o nome do arquivo contenha espaços. Isso precisaria adicionar aspas ao redor dos curingas.
fonte