You can't, which is one of the reasons why you never use for
that way to loop over the output of a command that returns file names. Also known as Bash Pitfall Number 1. If you use a while
loop instead, you will handle files with spaces just fine:
$ 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
However, that will still fail on file names that contain newlines:
$ 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
To get around that, and assuming your find
implementation supports it, you can use -print0
to print null-terminated lines, and then use a loop that uses the NUL byte as a separator. Like this:
$ 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
That said, by far the best approach is to use find's -exec
, which unlike -print0
is POSIX and portable, and also can handle arbitrary file names just fine:
$ find . -type f -exec date -r {} \;
Fri May 12 04:53:06 PM BST 2023
Fri May 12 04:51:42 PM BST 2023