This post explains how to add a line at the beginning of a file from the terminal. But how do I modify from the terminal a line somewhere in a file if I do not know which line it is?

I should modify the line eni=10.*10**9 to eni=10.*10**8 note the exponents. It is the second time that eni appears

  • Do you mean the exact middle of a file? – guillermo chamorro Sep 1 at 17:43
  • No I mean somewhere in the file – mattiav27 Sep 1 at 17:44
  • If not line number is there any pattern or some kind of phrase which is to be followed? Like add this line before a line which contains "blabla". – Kulfy Sep 1 at 17:50
  • @Kulfy it is the second time the term 'eni' appears if that can be useful – mattiav27 Sep 1 at 17:59
  • 4
    What exactly kind of modifications do you want? Please edit your question and try to make it more descriptive and specific. – Kulfy Sep 1 at 18:05

I think this is what you want:

line=$(grep -n -m2 "eni" file | tail -n1 | cut -f1 -d:)

sed -i $line's/9$/8/' file
  • @wjandrea modified the answer, take a look. – guillermo chamorro Sep 1 at 19:07
  • 2
    Nice! You could simplify getting the line number: line="$(awk '/eni/ {count+=1;if(count==2){print NR}}' test.txt)" – wjandrea Sep 1 at 19:13
  • 1
    This answer will match the second occurrence of eni and return the line number. Then it will change the last occurrence of 9 with 8 in that line. If more than one 9 are present in the same line, it will only change the last one and might miss the intended one. – Raffa Sep 1 at 20:22
  • 1
    @Raffa Yes, a more elaborate regex could be done, but OP's data doesn't show more text after the line, that's why I chose to simplify it to match what OP shows as a line. Note that OP wrote "I should modify the line", not x content in the line. – guillermo chamorro Sep 1 at 20:29
  • 1
    @guillermochamorro You did a good job, but I however recommend you add such explanation to your answer as it could prevent unintended modification to the file. Thank you – Raffa Sep 1 at 20:33

Since Ubuntu now ships with GNU Awk v4.0+ (which provides an inplace module) you could do something like

gawk -i inplace '/eni=/ {if (++c == 2) sub(/10\*\*9/,"10**8")} 1' file

You can make the regular expressions /eni=/ and/or /10\*\*9/ more or less specific as required.

Similarly in perl

perl -i -pe 'if (/eni=/) {s/10\*\*9/10\*\*8/ if (++$c == 2)}' file

Using sed:

sed -i ': 1 ; N ; $!b1 ; s/eni\=10\.\*10\*\*9/eni\=10\.\*10\*\*8/2' filename

/ is one of the delimiters and \ is the escape character. \ is used so that bash won't interpret special characters as some command, like * as wildcard.

  • This answer will match the second occurrence of eni=10.*10**9 in a new line and will change it with eni=10.*10**8. Run it only once. – Raffa Sep 1 at 20:22

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.