I'm looking to rename multiple files with the same name, with exception to the end of their file names. I want to replace the differing parts with an incremental counter. E.g. With the following files,

71116_123    71116_134    71116_113    71116_023
71116_923    71116_103    71116_125    71116_223

I want to rename them to

71116_1    71116_2    71116_3    71116_4
71116_5    71116_6    71116_7    71116_8

I found a similar question here , but the given solution seems somewhat complicated! Is there a simpler solution?

  • 2
    What is the relationship between the current suffix number and the new one? – jasonwryan Mar 20 '15 at 19:56

So, given the limited info you've given, let me state my assumptions which, if any are wrong, let me know and I/we can adjust the answer. The assumptions are critical to keeping the logic short and sweet, otherwise you do descend into 'overkill' mode.

Assumption 1. The 'suffix' for your file is what you want changed, and the 'suffix' is the number(s) after the underscore, meaning the underscore ( "_" ) is your separator.

Assumption 2. There will only ever be exactly one underscore in the original file name - not two or more underscores, and none without underscores

Assumption 3. You want the 'prefix', which is the value before the separator (as defined in Assumption 1) to remain exactly the same.

Assumption 4. Regardless of the original suffix, you want the new suffix to use the same separator (as defined in Assumption 1) and that the new suffix is incremented not by time stamp or any other value other than the sort order as it was prior to renaming (meaning, driven by the original alpha-numeric sort order of the file names).

Assumption 5. You want it fairly 'simple', which is unfortunately completely arbitrary, but I will define it as 'no complicated for loops or while loops' and 'not too many weird sed or awk' commands.

So, it is not a hard problem, but given the constraints listed, it does become and interesting challenge. Regardless, I still resorted to using a 'simple' for loop and a 'simple' awk:

for i in *; do
  let cnt=cnt+1
  mv "$i" "$(echo "${i}_${cnt}" | awk -F_ '{print $1"_"$3}')"

If there are other files in the same directory you don't want renamed, as was the case in my original testing (I was testing in the /tmp directory, which had other files I didn't want renamed), then filter with some part of the prefix, like so:

for i in 71116*; do
  let cnt=cnt+1
  mv "$i" "$(echo "${i}_${cnt}" | awk -F_ '{print $1"_"$3}')"

I did look at the answers in your link - and I agree those are egregious overkill, as are many of the answers on stackexchange. However, most 'overkill' answers rely on fewer assumptions, so in theory, they are more 'versatile' and/or more 'portable' than what I offer here.

| improve this answer | |

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.