2

I have a file abc.txt like below:

#%PAM-1.0
# Test file
# Hello World
#
# echo "Test"
/etc/init.d/xrdp start

# Comment again
echo "Hello again"

I wanted to insert a line as a first executable line after comments...So if I want to add a line echo "Batman" after all the lines start with #, how can I achieve that?

The output should look like below:

#%PAM-1.0
# Test file
# Hello World
#
# echo "Test"
echo "Hello Batman"
/etc/init.d/xrdp start

# Comment again
echo "Hello again"

Please note that the line will not be added after other comment line # Comment Again

I tried below but it doesn't work. I am very new to Bash scripting so need help from the experts here.

sed -i '#/a "echo "Batman"' abc.txt

Thanks for your help!

fedorqui
  • 275,237
  • 103
  • 548
  • 598
skjcyber
  • 5,759
  • 12
  • 40
  • 60

2 Answers2

4

Just use a flag to keep track of when this line was printed:

awk '!/^#/ && !f{print "Hello Batman";f=1}1' file

That is: when a line does not start with # and this happens for the first time, print the desired line. Then, set the flag so this does not happen again.

Finally, 1 triggers the print that outputs the current line.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thanks it is able to show the output properly. Can you please let me know how to update the file in same place? – skjcyber Nov 29 '16 at 22:14
  • 1
    @SKJ refer to this answer on [awk save modifications in place](http://stackoverflow.com/a/16529730/1983854). – fedorqui Nov 29 '16 at 22:15
  • 1
    Awesome! this helps...And the explanation has helped me to learn a lot about awk.. – skjcyber Nov 29 '16 at 22:23
1

Insert Before Known Text with GNU Sed

Using GNU sed, you can do what you want more easily by not making your pattern match overly-generic. In your actual corpus, you can insert the text before your first line, rather than trying to match any number of comment lines in a non-greedy way. For example:

$ sed --in-place '/^\/etc\/init.d\/xrdp start/i\echo "Batman"' /tmp/abc.txt
#%PAM-1.0
# Test file
# Hello World
#
# echo "Test"
echo "Batman"
/etc/init.d/xrdp start

# Comment again
echo "Hello again"

If you really need a more generic way to do this, you'll have to work harder to split your text into paragraphs or sections before munging the text. This is usually more work than is warranted, but your mileage may vary.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • Wait, you are using `--in-place` and the output shows in the screen? :O (it is a bit misleading). Also, note [you can use a different delimiter for a Regex](http://stackoverflow.com/documentation/sed/7720/regular-expressions/25336/using-different-delimiters#t=201611300742595009539) and say for example `sed '\|/etc/init.d/xrdp|i\echo "Batman"|' file`. – fedorqui Nov 30 '16 at 07:45