3

I want to move all files in my current directory to a directory named NewDir that end with *.bam, except for a specific file named special.file.bam.

I have found this command that removes all files, but not sure how to move them, not deleting them:

find . ! -name 'special.file.bam' -type f -exec rm -f {} +
0

4 Answers 4

8

If your shell is the bash shell, you can simply do as following by enabling the Extended Glob:

shopt -s extglob
mv -- !(special.file).bam temp/

to suppress the error:"bash: /usr/bin/mv: Argument list too long" when there are too many files matching the given pattern, do as following:

for file in !(special.file).bam; do
    mv -- "$file" temp/
done

or with the find command instead and portability:

find . -path './*' -prune -type f -name '*.bam' ! -name 'special.file.bam' \
    -exec sh -c 'for file; do mv "$file" temp/; done' sh_mv {} +

remove -path './*' -prune part to find files in sub-directories too.

0
2
 find . -maxdepth 1 -type f -name "*.bam" ! -name "special.file.bam" -exec mv {} NewDir \;
1
  • 2
    always use slash at the end of the second argument, like mv {} NewDir/ so in case NewDir directory was not exist your files all will not be overwrite on single file NewDir, instead mv will complain cannot move ...... 'NewDir/': Not a directory Commented May 17, 2021 at 19:29
2

If the number of files exceeds the command-line length, you still need to use find. I would suggest to combine it with xargs and null delimited files (\0), e.g.:

find . -maxdepth 1 -type f -name '*.bam' ! -name 'special.file.bam' -print0 |
xargs -0 mv -t /path/to/destination

Note: not exhaustively tested, use with care.

0
0
mv -f $(find ./*.bam -maxdepth 1 ! -name "special.file.bam" -type f) NewDir/ 
4
  • 2
    this will fail on files name having whitespaces or newline characters Commented May 17, 2021 at 15:28
  • It would also fail with "argument list too long" if there are a lot of names matching *.bam in the current directory.
    – Kusalananda
    Commented May 17, 2021 at 16:25
  • ok, thanks. But it worked in my instance. downrate is probably not needed. Commented May 17, 2021 at 16:26
  • All you need to do to fix your one-liner (provided too many files are not an issue) is: mv -f -- "$(find ./*.bam -maxdepth 1 -type f ! -name 'special.file.bam')" NewDir/ Note the quoting... it should take care of special filenames with \nand spaces in them or of files starting with hyphen(s). This said, αғsнιη 's answer is the more portable one.
    – Cbhihe
    Commented May 18, 2021 at 7:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .