I want to amend each line in a Text file using sed or alternative solution

Solution 1:

With sed:

sed 's/.*/<before> & and <after each line>/' input.txt > output.txt

Explanations

  • s/x/y/ – substitute x by y
  • .* – take the whole line
  • & – get matched text

The rest is just the text you want to add before and after &.

Solution 2:

With awk:

awk '{print before, $0, after}' before="<before>" after="and <after each line" input.txt > output.txt

This just prints the contents of the variable before, $0 (the current line) and the variable after, separated by spaces. The variables are set after the awk expression.

Solution 3:

With perl:

perl -ne 'chomp; print "<before> $_ and <after each line>\n"' in.txt > out.txt

These changes might be useful:

  • Replace <before> and and <after each line> with whatever you actually want to add.
  • Remove > out.txt to send the output to your terminal rather than to a file.
  • You can remove the input filename (in.txt) an enter input interactively for testing.

How it works:

  • -p makes the Perl interpeter operate on each line (see perldoc perlrun or man perlrun).
  • -e causes the next argument to be a perl script. So the part in ' ' is Perl code.
  • chomp removes the line terminator (newline) at the end of each line perl receives.
  • " " quoted string support interpolation. $_ is the line read. \n is a newline character.
  • perl will use in.txt as the input file. The > in > out.txt tells your shell to redirect output.

This command has the same effect, since -p (unlike -n) automatically prints each line ($_):

perl -pe 'chomp; $_ = "<before> $_ and <after each line>\n"' in.txt > out.txt

There are more sed-like ways to use perl. One advantage of the ways shown here is readability.

Solution 4:

You could also use coreutils:

n=$(wc -l < infile)
paste -d '' <(yes '<before>' | head -n $n) \
            infile                         \
            <(yes '</after>' | head -n $n)

Output:

<before>line 1</after>
<before>line 2</after>
<before>line 3</after>

Solution 5:

With vi/vim/ex, you can write a non-interactive one-liner for this, or do it in an open editor.

You can use either of these commands from your shell. They open the editor, add text to the beginning and end of each line, save the file with a different filename, and quit the editor:

ex in.txt '+%s/.*/<before> & and <after each line>/' '+wq out.txt'
vi in.txt '+%s/.*/<before> & and <after each line>/' '+wq! out.txt'

The first command uses ex mode and wq is sufficient to save the buffer as out.txt and quit. The second command uses vi mode and, since the changed buffer is still open and has not been saved into the original file, it requires the ! version of the command.

The second command also works in ex mode (and with vim instead of vi) but there's no reason to avoid ex for one-liners. The real reason I show the vi version that you can use it, with : instead of + in each command, to perform the change interactively while editing interactively in vi or vim.

With in.txt open in the editor (vim in.txt) you can run:

:%s/.*/<before> & and <after each line>/
:wq! out.txt

Whether your use the noninteractive or interactive version, they work the same way. vi and vim (and many other text editors in the "vi family") support search and replace with a sed-like syntax. You will notice the similarity to the sed method in dessert's answer:

  • .* is a regular expression that matches any character (.) zero or more times (*), thereby matching a whole line.
  • & signifies the whole match.
  • s/pattern/replacement/ replaces the first occurrence of pattern on a line with replacement.

sed automatically applies its script on each line. vi/vim/ex gives you more fine-grained control. %s performs the search and replace (s) action on all lines (%) and could also have been written 1,$s. If you wanted to change just one line you could write something like 3s (just the third line). Similarly you can change any range of lines, e.g., 3,10s for the third through tenth lines or 10,$s the tenth and all higher-numbered lines.