Search code examples
bashshellsh

Iterate over files in folder, rename them and switch the nth occurence of a character with another character


I need your help trying to understand how I could combine some actions to get to the expected results. So i have the following path, in which I have many files:

/home/application/Upload_Actions/TestFiles/

Now, the files have the following name:

DATE20220703.2130_Network=MainPipeline,Action=Upload_File,Element=X988Schema_1000_statsfile.csv

What I want is to iterate over all the files from within that folder, and replace the _ from its name with :. The file should look like:

DATE20220703.2130_Network=MainPipeline,Action=Upload_File,Element=X988Schema:1000_statsfile.csv

I have written a small one line for, but I am not quite sure how to iterate to the NTH occurence of the symbol _.

for f in ./*statsfile*; do mv "$f" "${f//_/:}"; done

The thing is that it does the following thing: From:

/home/application/Upload_Actions/TestFiles/DATE20220703.2130_Network=MainPipeline,Action=Upload_File,Element=X988Schema_1000_statsfile.csv

To: (but it failes doe to NO SUCH FILE or DIRECTORY because it replaces the _ from the path)

/home/application/Upload:Actions/TestFiles/DATE20220703.2130_Network=MainPipeline,Action=Upload:File,Element=X988Schema:1000:statsfile.csv

How could I do that only the 3rd occurence of the _ symbol gets replaced, so that the _ symbol from the path and the first _ symbol from from the title are left alone? Expected results:

/home/application/Upload_Actions/TestFiles/DATE20220703.2130_Network=MainPipeline,Action=Upload_File,Element=X988Schema:1000_statsfile.csv

OS Version: CENTOS 7


Solution

  • How about replacing the second occurence from the end? Like:

    for file in ./*statsfile*; do
      head=${file%_*_*}
      tail=${file#"$head"_}
      echo mv "$file" "$head:$tail"
    done
    

    Remove echo to actually move the files.