I have to rename a set of files, using the rename
command (with a regular expression).
After some tries, I'm not able to find an expression that gets the expected result.
I've got a file pattern like that:
prefix_some_name_other.txt
All files begin with the "prefix_
" string and end with "_other.txt
",
and the some_name part can consist of multiple (alphanumeric) words
separated by underscores.
So it's possible to have:
prefix_one_name_other.txt
prefix_this_is_my_name_1_this1_other.txt
I need to rename the filenames like these:
other_one-name_datetime other_this-is-my-name-1-this1_datetime
In other words:
- Need to delete "
prefix
" (leaving the underscore) - "
other
" token goes to the beginning of the file name - In some_name, convert underscore (_) to dash (-)
- The underscore at the end of the filename (after some_name) must remain
- Need to delete the
.txt
extension, replaced by datetime.
What I've tried:
rename 's/fw_([a-z]+)_(\d)_(\w+\d)_(\w+)\.txt/$4_$1-$2-$3_'$datahora'/' *.txt
$datahora
has datetime value (tested). This works as expected with
prefix_name_1_gnt1_other.txt
but not with
prefix_other_name_2_gnt2_other.txt
Where did I go wrong? How else could I accomplish that?
I have hanged my mind, since for now I'm not able to find a regex that works for all file names that I've got. I know, that the first element in the string is always the prefix
part, and the last element is then other.txt
part of the string. So is possible to split string into an array, and get the items that I need to build the new name. In fact, something like that.
datahora="20140718-080000"
arrfiles=( *.txt )
for curfile in ${arrfiles[*]}
do
arrparts=( ${curfile//_/ } )
numitems=${#arrparts[*]}
newname=""
for (( c=1; c<numitems-1; c++ ))
do
newname+="${arrparts[c]}-"
done
newname=${newname%-}
arrparts[numitems-1]=${arrparts[numitems-1]/.txt/}
newname="${arrparts[numitems-1]}_${newname}_$datahora"
echo "$curfile pasa a $newname"
mv ${curfile} ${newname}
done
After done in this way, I have give another try to @peterph suggestion, and finally done with some rename regex combinations. Somethink like that:
rename 's/_/-/g' *.txt
rename 's/^fw-(.*)-([^-]*)(\.txt)/$2.$1$3/' *.txt
rename 's/(\w+)\.(.*)(\.txt)/$1_$2_'$datahora'/' *.txt
I'm not sure what is the best aproach. In my opinion, the regex variant seems more elegant, but I need three rename operations (access three times to disk) to do the work, while the array
variant only writes once onto disk.
¿What do you think about those two solutions?...
Thank's again.