Suponha que eu tenha uma pasta contendo .txt , .pdf e outros arquivos. Gostaria de listar os "outros" arquivos (ou seja, arquivos sem as extensões .txt ou .pdf ). Você tem algum conselho sobre como fazer isso?
Eu sei como listar arquivos que não têm uma determinada extensão. Por exemplo, se eu quiser listar todos os arquivos, exceto os arquivos .txt , então
find -not -iname "*.txt"
ou
ls | grep -v '\.txt$' | column
parece funcionar. Mas como posso listar tudo, exceto arquivos .txt ou arquivos .pdf ? Parece que eu preciso usar algum tipo de "ou" lógico em find
ou grep
.
ls
vsfind
vs globbing pode diferir para arquivos de ponto ocultos.find
atravessará subdiretórios, como um recursivols
. Use-maxdepth 1
comfind
para que ele se comporte maisls
.Respostas:
Supondo que se tenha uma versão apropriada
ls
, esta é possivelmente a maneira mais simples:Se você deseja iterar em todos os subdiretórios:
fonte
ls
opções do GNU não são portáteis.ls
realmente não pertence a scripts portáteis, então eu suponho que o OP esteja perguntando apenas sobre uso interativo.Encontre suportes
-o
Você precisa dos parênteses para corrigir a precedência. O Find faz muitas coisas; Sugiro a leitura através de sua página de manual.
Você também pode fazer um ou dentro
grep
(mas, na verdade, não deve analisar a saída dels
)fonte
ls
?find
manual, recomendo sinceramente os artigos sobre Unix Power Toolsfind
, como docstore.mik.ua/orelly/unix3/upt/ch09_06.htm e docstore.mik.ua/orelly/unix3/upt/ch09_12.htmfind . NOT ( *.txt OR *.pdf )
Com
bash
o globbing prolongado (ligue comshopt -s extglob
), o glob!(*.txt|*.pdf)
deve funcionar. Você pode passar esse glob diretamente para qualquer comando que aceite argumentos de arquivo, incluindo, entre outrosls
.fonte
-d
para evitar isso:ls -d !(*.txt|*.pdf)
Em
zsh
comextendedglob
:ou
Ou com
kshglob
(sim, isso é ksh globbing e não "bash extended globbing"):Lembre-se, porém, de que eles também excluem arquivos de ponto.
O ksh93 possui o
FIGNORE
recurso (mis):fonte
Isso é equivalente ao comando do operador OR, devido às leis de De Morgan .
fonte
Conforme sugerido por derobert, sua melhor aposta é usar
find
. No entanto, é possível usar o resultado em um pipeline com outros comandos.O GNU (e alguns BSDs)
find
suportam o-print0
predicado que diz para imprimir o nome do arquivo terminado por um caractere NUL , que não é permitido em um nome de arquivo e garante que não haverá colisão. Outros comandos podem ser instruídos a usar o NUL como seu delimitador de entrada.O mais importante deles é o GNU
xargs
, que executa o comando que você especificar e transmite a lista de arquivos como argumentos da linha de comando. Você deseja executarxargs -r0
em conjunto com o find's,-print0
por exemplo:Isso imprime com segurança uma lista longa de diretórios de todos os arquivos pdf e txt , incluindo aqueles com espaços ou caracteres não imprimíveis no nome.
Você também pode usá-lo com o GNU da
tar
seguinte maneira:Isso cria um arquivo tar.gz de todos os arquivos cujos nomes não terminam em .tar.gz
rsync
também aceita arquivos delimitados por nulo com o-0
parâmetro, assim como vários outros. Masxargs
é a cola que você costuma usar para esse tipo de objetivo. Ou esse oufind
o-exec
recurso.fonte
tar
exemplo de comando é bom. Para a maioria dos propósitos, porém,-exec
é um ajuste melhor.Se você não possui um subdiretório
também deve funcionar!
Mas
é o caminho comum.
fonte
Como complemento, se você usar um shell compatível com bash, poderá usar a variável GLOBIGNORE para excluir resultados da correspondência de padrões. Do homem:
No seu caso particular:
Observe que eu executo esse comando como sub-shell (usando parênteses) para não alterar a variável de ambiente GLOBIGNORE do meu shell interativo.
fonte