-1

I need to add/insert a value "new content" on the secondlast line of the same file without deleting any of the lines or content of my file.

The condition is that the file content keeps changing and line numbers do not remain fixed.

Sample file:

library_path="usr/lib/1.0"
if test -n "/usr/local/lib64"; then
: ${PATH=${HOME}/lib:/usr/local/lib64}
else
: ${L_PATH=${HOME}/lib}
fi
if test -n "/usr/local/libs"; then
: ${PATH=${HOME}/lib:/usr/local/}
fi
##comment1
#comment2
##comment3
#comment4
if vals"${PATH}"; then
  PATH="${L_PATH}"
else
  PATH="${LD_PATH}:${Y_PATH}"
fi
export LD_PATH

I am trying the below command but its inserting the content on every line of the file:

sed -i 'x; s/.*/new content/;p;x; $d' myfile.txt

Any help appreciated !!

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
Automation Engr
  • 444
  • 2
  • 4
  • 26
  • i am looking for a linux command which will add text `new content` on second last line of the file irrespective if the number of lines/content of file changes dynamically – Automation Engr Dec 07 '20 at 17:49
  • Do you mean *replace* that line with `new content`, or *append* `new content` to that line, or *insert* `new content` as the second-to-last line? Please show us your desired output. – Beta Dec 07 '20 at 20:25
  • @Beta Below is the desired output, but the condition is that the file content keeps changing and i want to append a string everytime on second-last line only without deleting existing content and in the same file: ```library_path="usr/lib/1.0" if test -n "/usr/local/lib64"; then : ${PATH=${HOME}/lib:/usr/local/lib64} else : ${L_PATH=${HOME}/lib} fi if test -n "/usr/local/libs"; then : ${PATH=${HOME}/lib:/usr/local/} fi ##comment1 #comment2 ##comment3 #comment4 if vals"${PATH}"; then PATH="${L_PATH}" else PATH="${LD_PATH}:${Y_PATH}" fi new content export LD_PATH``` – Automation Engr Dec 08 '20 at 04:33

1 Answers1

1

To insert "new content" line as the second-to-last line into the file, use the Perl one-liner below. Example of usage:

echo "foo\nbar\nbaz" > in_file
perl -i.bak -ne 'push @a, $_; if ( eof ) { print for ( @a[0 .. ($#a-1)], "new content\n", $a[-1] ); }' in_file

Input:

foo
bar
baz

Output:

foo
bar
new content
baz

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-i.bak : Edit input files in-place (overwrite the input file). Before overwriting, save a backup copy of the original file by appending to its name the extension .bak.

push @a, $_; : Add the current line that was read from the input file into array @a. Thus, at the end of the file (eof), @a has the entire input file contents, 1 line per array element.
@a[0 .. ($#a-1)] : Lines 1 through the next-to-last line (inclusive). Note that arrays in Perl are 0-indexed.
$a[-1] : Last line.

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
  • I wanted the `new content` line to be part of the same original file `myfile.txt` and not in a new file ..... i am looking an equivalent to `sed -i` – Automation Engr Dec 07 '20 at 18:10
  • 1
    @AutomationEngr Added a method using `-i` switch, without using temp file. This Perl option is similar to `sed -i`. – Timur Shtatland Dec 07 '20 at 19:19
  • 1
    @TimurShtatland Great, This was what I was looking for. `sed -i` had some issues on my pc's linux version so i think i will go with perl, thanks again. – Automation Engr Dec 07 '20 at 19:26