2

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
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
sw-1966
  • 25
  • 5

1 Answers1

0
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 your find were replaced with something that could emit a path starting with a - instead of a ./, we wouldn't try to treat values in file as anything but positional arguments (filenames, in the context of stat, mkdir and mv).
  • 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 the mkdir if the stat fails, and we don't try to do the mv if the mkdir fails.
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441