
나한테 이상한 문제가 생겼어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
grep
PDF가 있는 행만 선택합니다 .- 공백을 제거
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
몇 가지 잘못된 점과 불필요한 복잡성이 있습니다.
- 이중
xargs
호출은 두 번째 호출이 한 줄의 입력을 확인하므로{}
일치하는 모든 파일 이름을 포함하는 단일 문자열로 한 번만 대체되지만echo
출력에는 이러한 차이가 표시되지 않음을 의미합니다(echo a b
와 비교echo "a b"
). - 인수 는 입력 인수 사이에 null( ) 문자가 필요하며 문자가 없음을
-0
의미합니다 . 이는 또한 입력이 단일 매개변수로 처리되도록 강제합니다.xargs
'\0'
- 조건이 일치할 때 파일 이름만 출력하면 한 줄에 하나의 파일 이름을 얻게 되며, 또는 가
xargs
필요 없이 직접 파이프로 연결할 수 있습니다 .grep
sed
- 불행하게도
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를 사용하여 모든 공백을 제거했기 때문에 안전한 가정).