ls 출력을 인용하는 중에 문제가 발생했습니다.

ls 출력을 인용하는 중에 문제가 발생했습니다.

일부 png 파일을 pdf로 병합하고 싶습니다. 주문하다

convert *png out.pdf

작동하지만 순서가 잘못되었습니다. 그것은 밝혀

ls -v *png

내가 원하는 순서가 주어지므로 그 출력을 변환에 전달하고 싶습니다.

나는 열심히 노력했다

convert `ls -v *png` out.pdf

그러나 파일 이름에 공백과 대괄호가 포함되어 있으므로 작동하지 않습니다.

ls큰따옴표를 통해 파일 이름을 설정하도록 지시합니다 .

convert `ls -vQ *png` out.pdf

교체 시 따옴표가 제거된 것처럼 보이기 때문에 작동하지 않습니다.

어떡해?

답변1

sort유사한 자연 정렬 버전을 제공하는 최신 GNU 기반 시스템이 있는 경우 -V이를 사용하여 정렬하고 결과를 배열로 읽을 수 있습니다.

while read -rd '' f; do 
  files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)

convert그러면 다음 명령으로 배열을 확장 할 수 있습니다 .

convert "${files[@]}" out.pdf

답변2

파일 이름에 개행 문자가 없으면 ls기본적으로 공백으로 분할되지 않는 개행 문자로만 출력을 분할하도록 쉘에 지시할 수 있습니다. 이것나뉘다변수에 의해 제어되며 IFS그 안에 포함된 모든 문자는 IFS구분 기호로 사용됩니다.

IFS=$'\n'      # set it to just a newline
convert $(ls -vd ./*.png) output.pdf 

파일 이름이 충분히 흥미롭거나 ls표시를 방해하는 경우 여전히 문제가 될 수 있습니다. 터미널로 인쇄할 때 ls파일은 일반적으로 여러 열에 나열됩니다. 그러나 출력이 터미널(쉘이 이를 읽는 곳)로 전송되지 않으면 마치 -1주어진 것처럼 동작합니다.


당신이 시작한 아이디어를 실현하려면,할 수 있다사용 eval.

eval: eval [arg ...]
ARG를 단일 문자열로 결합하고 결과를 셸에 대한 입력으로 사용하고 결과 명령을 실행합니다.

그러나 문제 eval는 명령줄의 모든 항목이 다시 구문 분석되고 일반적으로 안전한 항목도 구문 분석되지 않는다는 것입니다. 라는 이름의 파일을 상상해 보십시오 $(touch HELLO). 명령줄에서 해당 이름을 삭제하면 어떻게 될까요?

또한 이 경로를 사용하는 경우 쉘의 특수 문자 처리와 더 잘 일치할 수 있으므로 --quoting-style=shellnot을 사용하는 것이 좋습니다 . -Q(둘 다 GNU ls에만 국한된 것일 수도 있지만 내 생각 -v에도 그렇습니다.)

답변3

zshglob 한정자를 사용하면 (n)GNU와 유사한 정렬 순서가 제공됩니다 ls -v.

convert ./*.png(n) out.pdf

GNU 시스템에서는 , 또는 다음을 bash사용 합니다 .zshyashmkshksh93

eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf

답변4

GNU Parallel을 사용하면 다음과 같습니다:

ls -vd ./*png | parallel -Xj1 convert {} out.pdf

관련 정보