xargs가 작동하도록 구성할 수 없습니다.

xargs가 작동하도록 구성할 수 없습니다.

나한테 이상한 문제가 생겼어xargs.
나는 가지고있다xargs명령을 에코해도 완벽하게 작동하지만 작동하지 않는 구성입니다. 내 하나의 라이너는 다음과 같습니다.

 exiftool -p exifprintformat  -if '$Subject =~/DATA/i' -q  *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf  

그리고 출력

오류: 파일을 찾을 수 없습니다. 오류: PDF 파일을 열지 못했습니다: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf

  • exiftool제목 태그에 DATA라는 단어가 포함된 모든 PDF를 선택합니다 .
  • 파일 이름만 인쇄하라는 지시 -p exifprintformat가 있습니다 .exiftool
  • grepPDF가 있는 행만 선택합니다 .
  • 공백을 제거 sed합니다.
  • 첫 번째는 xarg모든 행을 하나의 문자열로 만들고 두 번째는 바인드 명령을 구성합니다.)

Exiftool -p EXIFprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -I{} echo pdftk {} cat 출력 바인더1.pdf

나는 얻다

pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf 고양이 출력 바인더1.pdf

완벽하게 작동합니다.

분명히 내가 뭔가 잘못하고 있는 것 같은데... 그런데 어쩌죠?

답변1

몇 가지 잘못된 점과 불필요한 복잡성이 있습니다.

  1. 이중 xargs호출은 두 번째 호출이 한 줄의 입력을 확인하므로 {}일치하는 모든 파일 이름을 포함하는 단일 문자열로 한 번만 대체되지만 echo출력에는 이러한 차이가 표시되지 않음을 의미합니다( echo a b와 비교 echo "a b").
  2. 인수 는 입력 인수 사이에 null( ) 문자가 필요하며 문자가 없음을 -0의미합니다 . 이는 또한 입력이 단일 매개변수로 처리되도록 강제합니다.xargs'\0'
  3. 조건이 일치할 때 파일 이름만 출력하면 한 줄에 하나의 파일 이름을 얻게 되며, 또는 가 xargs필요 없이 직접 파이프로 연결할 수 있습니다 .grepsed
  4. 불행하게도 xargs -I입력 줄당 하나의 명령을 강제하고 후행 매개변수를 추가하는 옵션은 없지만 간단한 해결 방법이 있습니다. 입력 스트림에 후행 매개변수를 추가하는 것입니다.

이것은 후행 매개변수가 추가된 단순화된 명령입니다( -if일치하는 PDF가 없는 상태에서 다른 조건으로 테스트했습니다).

{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
  echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk

xargs -d'\n'옵션을 사용하면 파일 이름에 공백이 포함된 경우 명령이 작동합니다.

답변2

xargs의 매뉴얼 페이지는 다음과 같이 말합니다.

-I 교체-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.

즉, " 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf" 라는 단일 인수로 끝나게 됩니다.

xargs를 모두 버리고 다음과 같이 명령 순서를 변경하는 것이 좋습니다.

pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf

이것은 모두 파일 이름에 공백이 없다고 가정합니다(어쨌든 sed를 사용하여 모든 공백을 제거했기 때문에 안전한 가정).

관련 정보