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>
andand <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 (seeperldoc perlrun
orman 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 lineperl
receives. -
"
"
quoted string support interpolation.$_
is the line read.\n
is a newline character. -
perl
will usein.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 ofpattern
on a line withreplacement
.
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.