I have 220 directories, each one with 2 files inside. all the files have the same termination (*.fq.gz). I want to move all these files to one unique directory.
I think I could do tha with a shell loop, but I don't have idea how to do that...
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityI have 220 directories, each one with 2 files inside. all the files have the same termination (*.fq.gz). I want to move all these files to one unique directory.
I think I could do tha with a shell loop, but I don't have idea how to do that...
This is something I use when I don't need to be extra careful
mkdir unique_dir && mv */*.fq.gz unique_dir/
Unless I missed something.
You are right. You can do this task with two for loops. One inside the other. We will create a bash script to do just that. Let's see how it would look like:
#!/bin/bash
for dir in */; do
echo "$dir"
cd "$dir"
for file in *; do
echo "moving $file"
mv $file ~/targetdir
done
cd ..
done
If you want to have a faster script just remove the echoing from the script. I made this to make it easy for tracking its progress.
Just create a file and copy these commands to it. After that, give it execution permission with chmod +x scriptfile
and run it with ./scriptfile
in the main directory where the other directories are located. Don't forget to replace targetdir and scriptfile with your target directory and script file name.
If you have more files in your directories, just replace *
with *.fq.gz
in the for file
loop and it will iterate only through your 2 files.
Warning!!! Don't create your target directory inside the main directory because it will iterate inside it as well.
Edit: as @steeldriver suggested, you could remove for dir
commands and just use for file
commands with*/*.fq.gz
to have a faster loop. I decided to mantain them for better tracking of whats going on inside directories.
Edit: While doing some research on man and web pages of find and xarg commands answered by @waltinator, I found it more convenient, faster and safe. I even found an alternative to xarg by using the -exec option of the find command such as find . -type f -name '*.fq.gz' -exec mv --backup=numbered --target-directory=$dest {} \;
.
~/targetdir
exists (and is a directory) otherwise your script will repeatedly overwrite the same file, potentially destroying all but the last one
Nov 19, 2019 at 2:19
cd
aren't really necessary - you might just as well do for file in */*
or for file in */*.fq.gz
. And don't forget to quote $file
(as you did for "$dir"
).
Nov 19, 2019 at 2:23
mv -t target file
mv
will fail if it's not a directory
Nov 19, 2019 at 12:10
When dealing with many files, or files with funny names, find
and xargs
are the tools to use. Read man find;man xargs
and do something like:
dest=../destination # must be outside this directory tree
mkdir $dest
find . -type f -name '*.fq.gz' -print0 |\
xargs -0 --no-run-if-empty echo mv --backup=numbered --target-directory=$dest
After you're happy with the results, replace "echo mv
" with just "mv
".
To exclude the $dest
is in current directory difficulty, use --prune
:
find . -type d -name "$dest" -prune -o -type f -name '*.fq.gz' -print0 |\
xargs -0 --no-run-if-empty echo mv --backup=numbered --target-directory=$dest
krusader can search files and save to a custom tab then you can select all of those (or filter the list) and move them to the destination
sudo apt install krusader
you might as well add
sudo apt install krename
go to the topmost source directory tools, search or crtl+s click feed to listbox edit select all file, copy to other panel or f5 other panel being the other tab which is the source target