Napseis
Napseis

Reputation: 863

batch rename folder deleting trailing characters

I have a lot of directory that end with "_ and 6 digits", eg:

diff_gb_and_pf_2voids_158543

I would like to find all that folders in the current folder, and rename them by deleting the "_" and the 6 digits at the end.

So far I'm stuck with this command:

find . -type d -print |grep '.*[0-9]\{6\}$' |xargs -I {} bash -c 'for i in {}; do mv "$i" ????; done;'

I can't find how to do the last step. I would try and call sed, but how ? Also, if there is a nicer way, please tell.

Thanks

Upvotes: 1

Views: 218

Answers (3)

janos
janos

Reputation: 124744

Here you go:

find /path -regex '.*_[0-9]\{6\}' -exec sh -c 'n="{}"; echo mv "{}" "${n%_*}"' \;

Check the output, if it looks good then drop the echo in there.

Explanation: for each matched file, we run a sub-shell, where we assign the filename to variable n, so that we can use pattern substitution ${n%_*}, which cuts off the last _ character and everything after it until the end of the filename.

Or here's a more portable way that should work in older systems too:

find /path -name '*_[0-9][0-9][0-9][0-9][0-9][0-9]' | sed -ne 's/\(.*\)_[0-9]\{6\}$/mv "&" "\1"/p'

Check the output, if it looks good than pipe it to sh (append this: | sh)

Explanation:

  1. The sed command receives the list of files to rename
  2. In the pattern we capture the first part of the filename within \( ... \)
  3. We replace the pattern with the text mv "&" "\1", where & is substituted with the pattern that was matched, in this case the entire original filename, and \1 is substituted with the part we captured within \( ... \)

Upvotes: 1

petrus4
petrus4

Reputation: 614

#!/usr/bin/env bash
set -x

ls -d diff* > dirlist

while IFS='_' read field1 field2 field3 field4 field5 field6
do
mv -v "${field1}_${field2}_${field3}_${field4}_${field5}_${field6}" \
"${field1}_${field2}_${field3}_${field4}_${field5}"
done < dirlist

Upvotes: 0

Steve
Steve

Reputation: 54542

Here's one way using your shell:

for i in $(find . -mindepth 1 -type d -regextype posix-extended -regex '.*_[0-9]{6}'); do 
    mv "$i" "${i%_*}";
done

Upvotes: 1

Related Questions