How to use find to copy and remove extensions while maintaining the same subdirectory structure

I am trying to copy all files from one directory to another by deleting all file extensions at once.

From directory 0001: 0001/a/1.jpg 0001/b/2.txt To directory 0002: 0002/a/1 0002/b/2 

I tried to find a few ... | xargs c ... p with no luck.

+6
source share
4 answers

Recursive copies are really easy with tar . In your case:

 tar -C 0001 -cf - --transform 's/\(.\+\)\.[^.]\+$/\1/' . | tar -C 0002 -xf - 
+4
source

If you don't have tar with --transform , this might work:

 TRG=/target/some/where SRC=/my/source/dir cd "$SRC" find . -type f -name \*.\* -printf "mkdir -p '$TRG/%h' && cp '%p' '$TRG/%p'\n" |\ sed 's:/\.::;s:/./:/:' |\ xargs -I% sh -c "%" 

There are no spaces after \ , you need a simple end to the line, or you can append it to one line, for example:

 find . -type f -name \*.\* -printf "mkdir -p '$TRG/%h' && cp '%p' '$TRG/%p'\n" | sed 's:/\.::;s:/./:/:' | xargs -I% sh -c "%" 

Explanation:

  • find will find all simple files that have extensions in the SRC (source) directory
  • find printf prepare the necessary shell commands:
    • to create the necessary directory tree in TRG (target directory)
    • copy command
  • sed do a cleanup of the cosmetic path (e.g. fixing /some/path/./other/dir)
  • xargs will take the whole line
  • and execute prepared commands using the shell

But it will be much better:

  • just make an exact copy in the first step
  • rename files in the second step

easier, cleaner and FASTER (no need to check / create target sub-racers)!

+2
source

Here you can find + bash + install, which will do the trick:

 for src in `find 0001 -type f` # for all files in 0001... do dst=${src/#0001/0002} # match and change beginning of string dst=${dst%.*} # strip extension install -D $src $dst # copy to dst, creating directories as necessary done 

This will change the permission mode of all copied files to rwxr-xr-x by default, it will be replaced with the install --mode option.

+1
source

I came up with this ugly duckling:

 find 0001 -type d | sed 's/^0001/0002/g' | xargs mkdir find 0001 -type f | sed 's/^0001//g' | awk -F '.' '{printf "cp -p 0001%s 0002%s\n", $0, $1}' | sh 

The first line creates a directory tree, and the second line copies the files. Problems with this:

  • There is only processing directories and regular files (no symbolic links, etc.).
  • If there are periods (except for the extension) or special characters (spaces, etc.) in the file names, then the second command will not work.
0
source

Source: https://habr.com/ru/post/926231/


All Articles