다음 내용을 포함하는 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)