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

최근 GNU 기반 시스템( sort비슷한 -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=shell대신 사용하는 것이 좋습니다. -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

관련 정보