Reputation: 1
I'm new to script writing so this may be a 'duh' question, and maybe sed/awk can't do this, I need to insert a user input line of text into a file but it has to be inserted just after a specific, and unique line. The line in question is like "### INSERT NEW INPUT BELOW HERE" I've been using:
sudo sed -i "9i$userinput from user" ~/filename;
which successfully inserts the user input plus additional text into the file right after the line "### INSERT NEW INPUT BELOW HERE" which happens to be at line 8 so I hard coded 9, but, as it turns out other scripts may add or subtract lines from this file prior to the line "### INSERT NEW INPUT BELOW HERE" which screws me all up... how can I identify the line number of the line with the text "### INSERT NEW INPUT BELOW HERE" and assign it to a variable so that maybe something like:
sudo sed -i "$(linenumber + 1)i$userinput from user" ~/filename;
might work.
I've tried:
line= "### INSERT NEW INPUT BELOW HERE";
linenum= sed -n '/$line/'= inputfile;
echo linenum;
and
linenum=$(awk 'NR == "$line"' ./inputfile)
echo $linenum;
along with several variations but linenum remains null.
Any help or suggestions?
Upvotes: 0
Views: 57
Reputation: 8412
You can also find and mark the line "### INSERT NEW INPUT BELOW HERE"
. after words take this line and add a newline character "\n" then append your new line after this newline character.
Command
sed 's/^\(### INSERT NEW INPUT BELOW HERE\).$/\1\n$userinput from user/g' ~/filename
Upvotes: 0
Reputation: 246847
With sed, find the line and a
ppend the new line
sed -i '/### INSERT NEW INPUT BELOW HERE/a your new line here' file
(see https://www.gnu.org/software/sed/manual/sed.html#Other-Commands for the intricacies of multi-line inserts)
Example: add a line of text after "52"
$ text="this is the new stuff"
$ seq 50 55 | sed "/52/a $text"
50
51
52
this is the new stuff
53
54
55
Upvotes: 1
Reputation: 44043
I would match the line directly instead of counting the numbers. Simplest way:
awk -v subst="$userinput from user" '{ print } /### INSERT NEW INPUT BELOW HERE/ { print subst }' filename.txt
Then redirect that to a file and move it back. Or, if you have GNU awk 4.1 or later, use
awk -i inplace -v subst="$userinput from user" '{ print } /### INSERT NEW INPUT BELOW HERE/ { print subst }' filename.txt
to apply the changes in place.
Explanation:
{ print }
This has an implicit "match anything" in the front (technically: "match the empty string", which everything contains), so this prints every line.
/### INSERT NEW INPUT BELOW HERE/ { print subst }
And on lines that match ### INSERT NEW INPUT BELOW HERE
(i.e., that contain the string) print the variable subst
, that is set to "$userinput from user"
with the -v
switch. The stuff between the slashes is technically a regex, but since in this case we just have to match a static string, we don't use any of their complicated features.
awk is more robust compared to sed here because sed will throw up if the user inputs something that has meaning for sed (such as backslashes). awk does not have this problem if the -v
switch is used.
And if you really just want the number, you can (very similarly) use
linenum=$(awk '/### INSERT NEW INPUT BELOW HERE/ { print NR }' filename.txt)
Upvotes: 1
Reputation: 1349
I don't think your script would work. Bash will fail if any spaces around the equal-sign (=) that's used to assign a value to a variable. Also your sed expression is incorrect. Or maybe you just mistyped that in stackoverflow, whatever.
Try this script
line="### INSERT NEW INPUT BELOW HERE";
linenum=`sed -n '/'"$line"'/=;q' inputfile`
echo $linenum;
Upvotes: 1