파일 목록에 공백이 있는 명령에 대한 인수로 명령 대체를 올바르게 사용하는 방법은 무엇입니까?

파일 목록에 공백이 있는 명령에 대한 인수로 명령 대체를 올바르게 사용하는 방법은 무엇입니까?

다음 내용을 포함하는 FILES라는 파일이 있다고 가정해 보겠습니다.

/path/to/something
/path/to/something/else
/path/to/something/else/with/a space
/path/to/something/else/again

다음과 같이 명령 대체를 사용하려고 하면:head -n 1 $(cat FILES)

나는 다음을 가질 것입니다 :

head: cannot open 'a' for reading: No such file or directory
head: cannot open 'space' for reading: No such file or directory

이 문제는 이스케이프 문자 \나 구분 기호를 사용하여 ""해결할 수 없습니다 . ''(왜인지는 모르겠습니다......)

이를 수행하는 올바른 방법은 무엇입니까?

편집하다:분명히 내 문제는 생각보다 간단합니다. 이 작업은 다음과 같습니다.

head "a space" no_space

그러나 이것은 그렇지 않습니다:

FILES='"a space" no_space'; echo $FILES; head $FILES

"a여기서는 , , space"3 개의 파일로 처리됩니다 no_space.
그렇다면... 구분 기호를 무시하지 않도록 쉘에 어떻게 요청합니까? (또는 이스케이프 문자)

편집 2:

해결책을 찾았습니다:

while read line; do head "$line"; done < FILES

루프를 사용하지 않는 사람이 있나요?

답변1

파일 이름에 공백을 허용하는 배열(NUL 또는 줄 바꿈은 제외)에 각 줄(줄 바꿈으로 끝나는)을 배치하는 올바른 솔루션은 다음과 같습니다.

$ readarray -t files <FILES

$ printf '<%s>\n' "${files[@]}"
</path/to/something>
</path/to/something/else>
</path/to/something/else/with/a space>
</path/to/something/else/again>

"${files[0]}"그런 다음 마지막 인덱스까지 모든 값을 사용할 수 있습니다.

쉘 실행 분할의 영향을 피하기 위해 각 인수를 인용하십시오.

FILES에 나열된 각 파일의 첫 번째 줄을 얻으려면 다음을 수행할 수 있습니다.

$ readarray -t files <FILES
$ head -n1 "${files[@]}"
first line on first file
first line on second file
...
...

답변2

스크립트 전에 사용하면 유용할 것입니다: set -f. 제안해주신 ikkachu님께 감사드립니다.

솔루션 1:

환경 IFS=$'\n':

IFS=$'\n' ; head -1  $(cat data)

솔루션 2:

또 다른 가능한 해결책은 정의된 경로 사이에 큰따옴표를 추가하는 것입니다 FILES.

"/path/to/something"
"/path/to/something/else"
"/path/to/something/else/with/a space"
"/path/to/something/else/again"

xargs결과를 얻는 데 도움이 됩니다.

cat FILES | xargs head -n1
#or
xargs head -n1 < FILES
#or
xargs head -n1 <<< $(cat FILES)

관련 정보