2

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...

1

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 {} \;.

5
  • 1
    Another warning... make absolutely sure that ~/targetdir exists (and is a directory) otherwise your script will repeatedly overwrite the same file, potentially destroying all but the last one – steeldriver Nov 19 '19 at 2:19
  • As well, the outer loop and 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"). – steeldriver Nov 19 '19 at 2:23
  • Fully agree with @steeldriver, better to use mv -t target file – bac0n Nov 19 '19 at 10:33
  • .... or at least add a trailing slash to the target so that mv will fail if it's not a directory – steeldriver Nov 19 '19 at 12:10
  • Thanks! You were very clear and your code was very helpfull – Luis Enrique Bizant Nov 20 '19 at 21:06
2

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.

0

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
1
  • 1
    you could exclude dest from find. – bac0n Nov 19 '19 at 6:52
-1
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.