Home > Net >  How to use regexp with find in -name and -path?
How to use regexp with find in -name and -path?

Time:07-22

I have a main folder that contains files and subfolders and I want to move all the graphic files (pdf, png, jpg, and so on) in a new folder callded figs (inside my main folder).

I want to exclude:

  • all the subfolders whose name starts with Copy_of_
  • all the folders whose name contains copy 1 and tikz
  • all the pdf files whose name starts with Copy_of_, XXX, YYY, ZZZ

I wrote this code:

# not pdf
find . -type f -regextype posix-extended -regex '.*(jbig2|jpeg|jp2|jpg|jpx|png)$' ! -path '*/Copy_of_*/*' ! -path '*/*copia 1*/*' ! -path '*/tikz*/*' ! -path 'figs' -print0 | xargs -0 -I {} mv {} "figs"

# pdf
find . -type f \( -name "*.pdf" ! -name "Copy_of_*" ! -name "XXX*" ! -name "YYY*"  ! -name "ZZZ*" \) ! -path '*/Copy_of_*/*' ! -path '*/*copy 1*/*' ! -path '*/tikz*/*' ! -path 'figs' -print0 | xargs -0 -I {} mv {} "figs"

I split my code into two parts because I can't manage it in one solution.

Is there a way to do it all with one call to find and/or to use regular expressions for -name and -path thus avoiding having to specify them one by one?

CodePudding user response:

You can do a lot of complex things when you go to town with grouping expressions (as you already did in your first find command, along with -and and -or). Check out the OPERATORS section of its man-page.

Something like this, for instance:

#!/bin/bash

find \
     . -type f \
     ! -path '*/Copy_of_*/*' \
     ! -path '*/*copia 1*/*' \
     ! -path '*/tikz*/*' \
     ! -path 'figs' \
     \( \( -regextype posix-extended -regex '.*(jbig2|jpeg|jp2|jpg|jpx|png)$' \) -or  \
        \( -name "*.pdf" ! -name "Copy_of_*" ! -name "XXX*" ! -name "YYY*"  ! -name "ZZZ*" \) \) \
     -print0 | \
    xargs -0 -I {} echo {}

This test snippet merely echos the files that it thinks it should move. For a quick test I created some (empty) files:

$ tree
.
|-- Copy_of_figs
|   `-- 1.jpg
|-- Copy_of_pdf_1.pdf
|-- Hello
|   |-- 1.jpg
|   |-- 2.png
|   `-- 3.pdf
|-- figs
|-- snippet.sh
`-- tikz
    `-- 4.pdf

4 directories, 7 files

Where this was the result:

$ ./snippet.sh
./Hello/2.png
./Hello/1.jpg
./Hello/3.pdf

Sidenote: You refer to copia 1 in one find statement and to copy 1 in another. Don't know if the former was a typo, or if both patterns needed to be excluded.

  • Related