
Eu tenho um problema estranho comxargs.
eu tenho umxargsconstrução que não funciona, embora quando eu repito o comando, funcione perfeitamente. Meu único forro é o seguinte:
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf
e a saída
Erro: Não foi possível encontrar o arquivo. Erro: Falha ao abrir o arquivo PDF: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
- O
exiftool
seleciona todos os pdf que contenham a palavra DATA na tag de assunto, - As
-p exifprintformat
instruçõesexiftool
para imprimir apenas o nome do arquivo, - O
grep
seleciona apenas as linhas com pdf, - O
sed
remove espaços em branco, - O primeiro
xarg
transforma todas as linhas em uma string e o segundo constrói o comando bind) quando executo
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -I{} echo pdftk {} cat output binder1.pdf
eu recebo
pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf cat output binder1.pdf
que funciona perfeitamente.
Obviamente, estou fazendo algo errado...Mas o quê?
Responder1
Existem várias coisas erradas e uma complexidade desnecessária: -
- A chamada dupla
xargs
significa que o segundo vê uma única linha de entrada, portanto{}
é substituído apenas uma vez por uma única string contendo todos os nomes de arquivos correspondentes, masecho
não mostra essa diferença na saída (compareecho a b
comecho "a b"
). - O
-0
argumento significa quexargs
precisa de um'\0'
caractere nulo ( ) entre os argumentos de entrada e não há nenhum; isso também força a entrada a ser tratada como um único parâmetro. - Ao gerar apenas o nome do arquivo quando a condição corresponder, você obtém um nome de arquivo por linha, que pode ser canalizado diretamente
xargs
sem a necessidade degrep
oused
. - Infelizmente,
xargs -I
força um comando por linha de entrada e não há opção para adicionar parâmetros finais, mas há uma solução simples: adicionar os parâmetros finais ao fluxo de entrada.
Este é um comando simplificado com os parâmetros finais adicionados (testei com uma -if
condição diferente, não tendo nenhum PDF correspondente): -
{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk
A xargs -d'\n'
opção faz o comando funcionar quando os nomes dos arquivos possuem espaços em branco incorporados.
Responder2
A página de manual do xargs diz:
-Eu substituo-str
Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.
Em outras palavras, você acabará com um único argumento chamado " 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
"
Sugiro abandonar completamente o xargs e reordenar seu comando mais ou menos assim:
pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf
Tudo isso pressupõe que você não tenha espaços em seus nomes de arquivos (suposição segura, já que você estava removendo todos os espaços com sed de qualquer maneira).