Leos Literak
Leos Literak

Reputation: 9406

Strip ./ from filename in find -execdir

Whole story: I am writing the script that will link all files from one directory to another. New file name will contain an original directory name. I use find at this moment with -execdir option.

This is how I want to use it:

./linkPictures.sh 2017_wien 2017/10

And it will create a symbolic link 2017_wien_picture.jpg in 2017/10 pointing to a file 2017_wien/picture.jpg.

This is my current script:

#!/bin/bash
UPLOAD="/var/www/wordpress/wp-content/uploads"
SOURCE="$UPLOAD/photo-gallery/$1/"
DEST="$UPLOAD/$2/"
find $SOURCE -type f -execdir echo ln -s {} $DEST/"$1"_{} ";"

It prints:

ln -s ./DSC03278.JPG /var/www/wordpress/wp-content/uploads/2017/10/pokus_./DSC03278.JPG

This is what I want:

ln -s ./DSC03278.JPG /var/www/wordpress/wp-content/uploads/2017/10/pokus_DSC03278.JPG

How to implement it? I do not know how to incorporate basename into to strip ./.

Upvotes: 2

Views: 252

Answers (2)

anubhava
anubhava

Reputation: 786031

You can use this find with bash -c:

find $SOURCE -type f -execdir bash -c 'echo ln -s "$2" "/$DEST/$1"_${2#./}' - "$1" '{}'  \;
  • ${2#./} will strip starting ./ from each entry of find command's output.
  • $1 will be passed as is to bash -c command line.

If you have large number of files to process I suggest using this while loop using a process substitution for faster execution since it doesn't spawn a new bash for every file. Moreover it will also handle filenames with white-spaces and other special characters:

while IFS= read -r file; do
    echo ln -s "$file" "/$DEST/${1}_${file#./}"
done < <(find "$SOURCE" -type f -print0)

Upvotes: 2

janos
janos

Reputation: 124804

To run basename on {} you would need to execute a command through sh:

find "$SOURCE" -type f -execdir sh -c "echo ln -s '{}' \"$DEST/${1}_\$(basename \"{}\")\"" ";"

This won't win any speed contests (because of the sh for every file), but it will work.

All the quoting may look a bit crazy, but it's necessary to make it safe for files that may contain spaces.

Upvotes: 2

Related Questions