Question

I want to prepend text to the name of every file of a certain type - in this case .txt files - located in the current directory or a sub-directory.

I have tried:

find -L . -type f -name "*.txt" -exec mv "{}" "PrependedTextHere{}" \;

The problem with this is dealing with the ./ part of the path that comes with the {} reference.

Any help or alternative approaches appreciated.

Was it helpful?

Solution

You can do something like this

find -L . -type f -name "*.txt" -exec bash -c 'echo "$0" "${0%/*}/PrependedTextHere${0##*/}"' {} \;

Where

  • bash -c '...' executes the command
  • $0 is the first argument passed in, in this case {} -- the full filename
  • ${0%/*} removes everything including and after the last / in the filename
  • ${0##*/} removes everything before and including the last / in the filename

Replace the with a once you're satisfied it's working.

OTHER TIPS

Are you just trying to move the files to a new file name that has Prepend before it?

for F in *.txt; do mv "$F" Prepend"$F"; done

Or do you want it to handle subdirectories and prepend between the directory and file name:

dir1/PrependA.txt
dir2/PrependB.txt

Here's a quick shot at it. Let me know if it helps.

for file in $(find -L . -type f -name "*.txt")
do
parent=$(echo $file | sed "s=\(.*/\).*=\1=")
name=$(echo $file | sed "s=.*/\(.*\)=\1=")
mv "$file" "${parent}PrependedTextHere${name}"
done

This ought to work, as long file names does not have new line character(s). In such case make the find to use -print0 and IFS to have null.

#!/bin/sh
IFS='
'
for I in $(find -L . -name '*.txt' -print); do
    echo mv "$I" "${I%/*}/prepend-${I##*/}"
done

p.s. Remove the echo to make the script effective, it's there to avoid accidental breakage for people who randomly copy paste stuff from here to their shell.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top