0

I have multiple files in one directory with below format, so I want to rename all like below:

From

27_07_2017file1vc001vpxd-1605.log
27_07_2017case2vc001vpxd-9169.log
27_07_2017server3vc001vpxd-4640.log
27_07_2017file24vc001vpxd-9170.log
27_07_2017files5vc001vpxd-4641.log

To

file1vc001vpxd-1605_27_07_2017_1.log
case2vc001vpxd-9169_27_07_2017_1.log
server3vc001vpxd-4640_27_07_2017_1.log
file24vc001vpxd-9170_27_07_2017_1.log
files5vc001vp-4641_27_07_2017_1.log

Need to change on format of files from datefilename.log to format filename.date_1.log

Please not to suggest using rename command, since it doesn't work in my linux server.

Thank you

  • Have you tried mv 07-2017filename.log filename_31-07-2017_1.log? If you post your script code and a error message we might be able to help you more. – Tigger Aug 1 '17 at 4:36
  • why doesn't rename work? is it not installed? do you only have the primitive rename from util-linux? In either case, install the perl File::Rename version of rename. It can easily do exactly what you want and is the best tool for this job. It's in the rename package on debian-like distros, and many others also have their own package of File::Rename – cas Aug 1 '17 at 8:46
2

Here is a bash script for that (revised for general case based on OP's revised question):

for file in *.log; do 
    echo mv "$file" "${file:10:$((${#file}-14))}".${file::10}_1.log;
done

Above the ${file:X:Y} is bash substring expansion syntax ${variable:offset:length} and get length of characters start from offset from its variable (or parameter) and rename with mv command. Just remove the echo once you ensure the result is expected as you want.

The result of above is as following:

mv 27_07_2017case5.log case5.27_07_2017_1.log
mv 27_07_2017file1vc001vpxd-1605.log file1vc001vpxd-1605.27_07_2017_1.log
mv 27_07_2017file2vc001vpxd-9169.log file2vc001vpxd-9169.27_07_2017_1.log
mv 27_07_2017file3vc001vpxd-4640.log file3vc001vpxd-4640.27_07_2017_1.log
mv 27_07_2017file4vc001vpxd-9170.log file4vc001vpxd-9170.27_07_2017_1.log
mv 27_07_2017file5.log file5.27_07_2017_1.log
mv 27_07_2017file5vc001vpxd-4641.log file5vc001vpxd-4641.27_07_2017_1.log
mv 27_07_2017number-blahblahblah5.log number-blahblahblah5.27_07_2017_1.log
mv 27_07_2017number-blahblahblah5AAABBC.log number-blahblahblah5AAABBC.27_07_2017_1.log
mv 27_07_2017number5.log number5.27_07_2017_1.log
0

I don't know all possible cases for filenames, so I'll show you a general approach you can adapt to your needs.

You can loop through your files with a for loop or use find -exec as you like. I think you mainly want to know how to cut your filename to pieces and set them together differently.

You can either pipe the name into a tool like sed and create a regular expression to identify the pieces you need:

newname=`echo "$oldname"|sed -E 's/([0-9-]{10})(.*).log/\2_\1_1.log/'`

If you place () around those parts you can refer to them as \1, \2 and so on in the replacement string. If you need to adapt it, read the man page of sed or ask here if you don't succeed.

The other possibility is to use POSIX variable expansion:

You probably know that

${oldname#*201?}

will remove the date prefix of your filename (the ? can match any character, so this works for years 2010 to 2019, if that's sufficient. Otherwise adapt.)

You can also combine them:

${oldname%${oldname#*201?}}

Will remove the part we extracted above, so this will give you the date only. This way you can separate the parts of the filename and paste them in a different order.

  • Thanks. But I have few files with different , plz treat above above filename as file1 , file2 , file3, file4, case1, case2 , number1, number2...and so on. The word "file" is not fixed in all filename – Nirmal Aug 1 '17 at 6:22
  • same format means - it should renamed as <filename>_<date>.1.log In other way , it should cut middle name which is after date and keep first and date middle and so on – Nirmal Aug 1 '17 at 6:22
  • Of course you have multiple files. But by using a loop like for oldfile in *.log; do you can use the given commands as $oldfile will carry a different filename in each iteration. – Philippos Aug 1 '17 at 6:38
  • My Org won't allow to use sed cmd. Are you asking me to try same as below- for oldfile in *.log; do mv $oldfile ${oldname%${oldname#*201?}}; done. Above will give strip the date only. can you help me in separating the parts of the filename and paste them in a different order which i mentioned in my edited question. – Nirmal Aug 1 '17 at 6:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.