I have a task where I need to move a bunch of files from one directory to another. I need move all files with the same file name (i.e. blah.pdf, blah.txt, blah.html, etc...) at the same time, and I can move a set of these every four minutes. I had a short bash script to just move a single file at a time at these intervals, but the new name requirement is throwing me off.
My old script is:
find ./ -maxdepth 1 -type f | while read line; do mv "$line" ~/target_dir/; echo "$line"; sleep 240; done
For the new script, I basically just need to replace find ./ -maxdepth 1 -type f
with a list of unique file names without their extensions. I can then just replace do mv "$line" ~/target_dir/;
with do mv "$line*" ~/target_dir/;
.
So, with all of that said. What's a good way to get a unique list of files without their file names with bash script? I was thinking about using a regex to grab file names and then throwing them in a hash to get uniqueness, but I'm hoping there's an easier/better/quicker way. Ideas?
A weird-named files tolerant one-liner could be:
If the files can start with multiple prefixes, you can use logic operators in find. For example, to move blah.* and foo.*, use:
EDIT
Updated after comment.
Here's how I'd do it:
Perhaps it needs some explaination:
find ./ -type f -printf '%f\n':
find all files and print just their name, followed by a newline. If you don't want to look in subdirectories, this can be substituted by a simplels
;sed 's/\..*//'
: strip the file extension by removing everything after the first dot. Bothfoo.tar
adfoo.tar.gz
are transformed intofoo
;sort | unique
: sort the filenames just found and remove duplicates;(
: open a subshell:while read filename
: read a line and put it into the$filename
variable;find . -type f -iname "$filename"'*' -exec mv {} /dest/dir \;
: find in the current directory (find .
) all the files (-type f
) whose name starts with the value infilename
(-iname "$filename"'*'
, this works also for files containing whitespaces in their name) and execute themv
command on each one (-exec mv {} /dest/dir \;
)sleep 240
: sleep)
: end of subshell.Add
-maxdepth 1
as argument tofind
as you see fit for your requirements.