command-line — como passar o resultado de `find` como uma lista de arquivos?
/como passar o resultado de `find` como uma lista de arquivos?
como passar o resultado de `find` como uma lista de arquivos?
A situação é, eu tenho um MP3 player mpg321 que aceita uma lista de arquivos como argumento. Eu mantenho minha música em um diretório chamado "music", no qual existem mais alguns diretórios. Eu só quero jogar todos eles, então executo o programa com
. O problema é que alguns nomes de arquivo têm um espaço em branco e o programa divide esses nomes em partes menores e reclama da falta de arquivos. Envolvendo o resultado de find entre aspas
não ajuda porque tudo se tornará um grande "nome de arquivo", que obviamente não foi encontrado.
Como posso fazer isso então? Se isso for importante, estou usando bash, mas mudarei para zsh em breve.
1 de out. de 2010 phunehehe
Tente usar find's -print0 ou -printf opção em combinação com xargs assim:
Como isso funciona é explicado por página de manual do find :
Verdade; imprime o nome completo do arquivo na saída padrão, seguido por um caractere nulo (em vez do caractere de nova linha que -print usa). Isso permite que nomes de arquivo que contenham novas linhas ou outros tipos de espaço em branco sejam interpretados corretamente por programas que processam a saída de localização. Esta opção corresponde à opção -0 de xargs.
1 de out. de 2010 Steven D
Com GNU find, você também pode usar -print0 e xargs -0 , mas não adianta aprender outra ferramenta. O -exec ... {} + a sintaxe recebe pouca menção porque o Linux a adquiriu depois de -print0, mas não há motivo para não usá-lo agora.
Com zsh ou bash 4, isso é muito mais simples:
Apenas no zsh, você pode tornar um (parte de um) padrão sem distinção entre maiúsculas e minúsculas:
1 de out. de 2010 Gilles 'SO- stop being evil'
Eu acho solução de Steven é melhor, mas outra maneira é usar xargs '-I flag, que permite especificar uma string que será substituída no comando pelo argumento (em vez de apenas anexar o argumento no final do comando). Você pode usar isso para citar o argumento:
1 de out. de 2010 Michael Mrozek
Normalmente, é melhor -exec ${tgt_process} \{\} + mas se você fizer precisa para obter uma lista delimitada de forma confiável de nomes de arquivos em um arquivo ou fluxo de find por qualquer motivo, você pode fazer isso:
O que você ganha com isso são duas únicas strings. No cabeçalho de cada nome de arquivo está a string \n/// e no final de cada nome de arquivo está a string ///\n. Essas duas strings não ocorrem em nenhum outro lugar na saída de find, exceto nessas posições, independentemente de quaisquer caracteres que os nomes de arquivo contenham.
Além disso, o uso acima é a linha de base POSIX portátil e pode funcionar em quase qualquer sistema Unix. Isso não é verdade para o uso de um delimitador de byte nulo - apesar de sua conveniência - recomendado por alguns outros.
Mas, novamente, isso só é necessário se você não puder -exec seu $tgt_process por qualquer motivo, pois esse deve ser o seu objetivo. Por um lado, o método acima ainda requer análise. Por exemplo, se você quiser que cada nome de arquivo Shell seja citado, primeiro você terá que garantir que todas as aspas no nome do arquivo sejam escapadas:
Isso gera uma matriz de nomes de arquivos com escape de Shell adequado, independentemente de quaisquer que sejam seus caracteres constituintes. Agora você só tem que esperar que seu aplicativo na extremidade receptora não o estrague.
10 de jun. de 2014 mikeserv
Outra maneira de fazer isso é escapar de todos os caracteres especiais que vêm nos nomes dos arquivos. Por exemplo.:
Isso basicamente passará os nomes de arquivo com escape adequado para xargs para execução e não haverá problemas.
10 de jun. de 2014 Priyabrata Patnaik
Como usar ln -s para criar um atalho de linha de comando?
É possível que um programa obtenha vários espaços entre os argumentos da linha de comando no POSIX?
Por que prefere `sort <" $ f1 "` em vez de `sort -" $ f1 "`, e por que isso é preferido em vez de `sort" $ f1 "`?