Reputation: 863
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
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:
sed
command receives the list of files to rename\( ... \)
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
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
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