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
예. 이것은 find
and 루프를 사용할 때 잘 알려진 문제 중 하나입니다.
이 문제를 해결하는 간단한 방법은 발견된 목록을 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와 다르고 이식 가능하며 임의의 파일 이름을 매우 잘 처리하는 -exec
find 를 사용하는 것입니다.-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