I am writing a simple method to mass move files and have attempted two approaches:
#(1)
find . -name '*.pdf' | xargs -I{} mkdir pdfs; mv {} pdfs
#(2)
find . -name '*.pdf' -exec mv {} pdfs +
The first approach surprisingly worked 'sometimes', however, after deleting the folder with the pdfs a few times and returning the pdfs to the parent directory, it suddenly stopped working.
It produces the following error:
mv: rename {} to pdfs: No such file or directory
xargs: unterminated quote
Whereas the second approach gives the following error:
find: -exec: no terminating ";" or "+"
Update:
I got it working with:
find . -name '*.pdf' -exec mv "{}" pdfs \;
However, If I wanted to create the directory and move files in one line, this wont work, for example:
find . -name '*.csv' -exec mkdir -p csvs && mv "{}" csvs \;
find: -exec: no terminating ";" or "+"
How to implement directory creation and move?
man 1 find
and read the entries on-exec
closely. Hint: the position of{}
matters. – Stefan van den Akker Jan 01 '23 at 13:25find . -name '*.csv' -exec bash -c 'mkdir csvs' bash 'mv {} csvs' \;
however this seems to recursively create the final and so move is never completed. – Emil11 Jan 01 '23 at 13:41bash -c 'mkdir csvs'
to only execute once? – Emil11 Jan 01 '23 at 13:44find -exec <command> \;
always executescommand
once for each of its matches. Why not:mkdir foo; find . -name bar -exec mv -t foo {} \;
? – Stefan van den Akker Jan 01 '23 at 14:08mkdir csvW; find . -name '*.csv' -print0 -exec bash -c $'\0' mv -t csvW {} \;
based on your interpretation, but the separator does not seem to work. – Emil11 Jan 01 '23 at 14:26-exec mv -t csvW {} +
is completely robust. You are needlessly complicating things and breaking support for arbitrary file names. See also https://mywiki.wooledge.org/BashFAQ/020 – tripleee Jan 01 '23 at 14:29-t
option tomv
is a GNU extension; it is available on most Linuxes, but on other systems commonly requires you to separately install the GNU userspace utilities.) – tripleee Jan 01 '23 at 14:31-t
, and likely what caused my previous comment. – Emil11 Jan 01 '23 at 14:32find . -maxdepth 1 -name '*.csv' -type f -exec mv csvW {} \+
, I get that the .csv fileis not a directory
, am I mis-specifying something? – Emil11 Jan 01 '23 at 14:36-t
you can't do that; you are saying to movecsvW
and all the other files onto the last found file. Try insteadfind ... -exec sh -c 'mv "$@" "$0"' csvW {} +
– tripleee Jan 01 '23 at 14:37