I created a bunch of folders from modification dates, like these: .. 2012-11-29 2012-11-20 ..
Now I want to move files into these folders, in case the have a modification date that equals the folders name. The files contain whitespace in their names.
If I run this I get a list that looks like the folder names:
find . -iname "*.pdf" -print0 | while read -d $'\0' file; do stat -c "%.10y" "$file"; done
How do I take this output and use it in a script that moves these files like (pseudocode):
find . -iname "*.pdf" -print0 | while read -d $'\0' file; do mv $<FILEWITHWHITESPACEINNAME> <FOLDERNAMEDLIKE $file stat -c "%.10y" "$file" > ; done
CodePudding user response:
find . -iname "*.pdf" -print0 |
while IFS= read -r -d '' file; do
folder=$(stat -c "%.10y" -- "$file") || continue # store date in variable
[[ $file = ./$folder/$file ]] && continue # skip if already there
mkdir -p -- "$folder" || continue # ensure directory exists
mv -- "$file" "$folder/" # actually do the move
done
- To read a NUL-delimited name correctly, use
IFS=
to avoid losing leading or trailing spaces, and-r
to avoid losing backslashes in the filename. See BashFAQ #1. - Inside your shell loop, you have shell variables -- so you can use one of those to store the output of your
stat
command. See How do I set a variable to the output of a command in bash? - Using
--
signifies end-of-arguments, so even if yourfind
were replaced with something that could emit a path starting with a-
instead of a./
, we wouldn't try to treat values infile
as anything but positional arguments (filenames, in the context ofstat
,mkdir
andmv
). - Using
|| continue
inside the loop means that if any step fails, we don't do the subsequent ones -- so we don't try to do themkdir
if thestat
fails, and we don't try to do themv
if themkdir
fails.