for-do 루프는 공백이 포함된 파일 이름에서 작동하지 않습니다.

for-do 루프는 공백이 포함된 파일 이름에서 작동하지 않습니다.
for X in $(find ~/Documents/ -type f);do date -r "${X}";done

위 줄은 "/Documents/"의 파일 이름에 공백이 포함되어 있지 않으면 제대로 작동합니다.
그러나 파일 이름에 공백이 포함되어 있으면 다음 오류가 나타납니다.

 No such file or directory

공백이 포함된 파일 이름에 대해 어떻게 작동하게 할 수 있나요?

답변1

루프를 사용하지 말고 -exec다음 매개변수를 사용하세요 find.

find ~/Documents/ -type f -exec date -r {} \;

답변2

예. 이것은 findand 루프를 사용할 때 잘 알려진 문제 중 하나입니다.

이 문제를 해결하는 간단한 방법은 발견된 목록을 stdout에 덤프하는 것입니다 read.

find ~/Documents/ -type f |
while IFS= read -r filename
do
    date -r "$filename"    # ... or any other command using $filename
done

명령이 충분히 작은 경우 -exec다음 키를 사용할 수 있습니다 find.

find ~/Documents/ -type f -exec date -r '{}' \;

답변3

for그렇게 할 수 없습니다. 이것이 파일 이름을 반환하는 명령의 출력을 반복하는 데 이 방법을 사용하지 않는 이유 중 하나입니다. 또한 ~으로 알려진배쉬 트랩 No. 1. while루프를 사용하면 공백이 있는 파일을 문제 없이 처리할 수 있습니다.

$ ls
'a file with spaces'
$ find . -type f | while read -r X; do date -r "$X"; done
Fri May 12 04:51:42 PM BST 2023

그러나 개행 문자가 포함된 파일 이름의 경우에는 여전히 실패합니다.

$ touch "$(printf 'a file with\na newline')"
$ ls
'a file with'$'\n''a newline'  'a file with spaces'
$ find . -type f | while read -r X; do date -r "$X"; done
date: './a file with': No such file or directory
date: 'a newline': No such file or directory
Fri May 12 04:51:42 PM BST 2023

이 문제를 해결하려면 구현에서 이를 지원한다고 가정하고 null로 끝나는 줄을 인쇄한 다음 NUL 바이트를 구분 기호로 사용하는 루프를 find사용할 수 있습니다 . -print0이와 같이:

$ find . -type f -print0 | while IFS= read -r -d '' X; do date -r "$X"; done
Fri May 12 04:53:06 PM BST 2023
Fri May 12 04:51:42 PM BST 2023

즉, 지금까지 가장 좋은 방법은 POSIX와 다르고 이식 가능하며 임의의 파일 이름을 매우 잘 처리하는 -execfind 를 사용하는 것입니다.-print0

$ find . -type f -exec date -r {} \;
Fri May 12 04:53:06 PM BST 2023
Fri May 12 04:51:42 PM BST 2023

관련 정보