I want to edit the file contents in the 2nd row and 2nd column ,which is a file name from that I want to remove the part after the last underscore and before the file extension .

The contents of the file looks like below Input file contents

01 |com_101_00000_0001_a234.txt|100

resultant file content

01 |com_101_00000_0001.txt|100

The number of underscores may vary depending upon the file names present inside the .ctl files.there are multiple files in a folder likes this ,i want to change the contents for all .ctl file in the 2nd row similarly.

Operating system details Linux  2.6.32 -696.30.1.e16
  • Title does not match question (hence the current answer, it answers the title, but not the body of the question). Please amend. – ctrl-alt-delor Dec 7 '18 at 8:38


awk -F\| -vOFS=\| 'NR==2 {sub (/_[^_]*\./,".", $2)}1' file
01 |com_101_00000_0001.txt|100

NR==2       if record count is 2 (i.e. 2. line)
sub (       `awk` "substitute" function
/_[^_]*\./  regex: match string consisting of multiple non-underscores, delimited by leading underscore and trailing literal dot
,".",       with a literal dot
 $2)        in second field
1           do default action: print

Redirect > into temp file, and mv / cp back to original file if desired. For multiple files, run in a for loop for all relevant files.

  • How can i modify this for multiple files in a directory?Now it works only for one file ,i want to edit the original files ..Also Can you please help by explaining how it works ? i know F is for field separator,and NR for number of rows ,but the regular expression all together not able to understand how it works ? – Vinay Dec 7 '18 at 13:00
  • Edited answers in... – RudiC Dec 7 '18 at 13:14
  • Great thanks for the explanation ,really helped for file in *.ctl do awk -F\| -vOFS=\| 'NR==2 {sub (/_[^_]*\./,".", $2)}' "$file" > tmpfile && mv tmpfile "$file" ; done Something wrong with the code i written ,getting empty files generated.some basic issues i feel ,please help to correct – Vinay Dec 7 '18 at 13:26
  • I can't find an immediate error in your loop (except a missing ; in front of do). Do you have the desired output for single file execution? – RudiC Dec 7 '18 at 14:01

Change the contents of files with regex;

perl -pi -e 's/_[^_\.]+(\.)/$1/g' *

Old answer before the question changed; Change file names with regex;

rename 's/_[^_\.]+(\.)/$1/g' *

It is written in perl, so is portable.


  • @user1133275 i have edited my question , was wrongly described earlier.i want to edit the file content not the file name – Vinay Dec 7 '18 at 8:50

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.