How can I insert a set of lines (about 5) into a file at the first place a string is found?
For example:
BestAnimals.txt
dog
awk -v insert=giraffe -v before=cat '
$1 == before && ! inserted {
print insert
inserted++
}
{print}
' BestAnimals.txt > NewBestAnimals.txt
An awk solution:
awk '/cat/ && c == 0 {c = 1; print "giraffe"}; {print}' \
BestAnimals.txt
If the animals you want to insert are in "MyOtherBestAnimals.txt" you can also do
awk '/cat/ && c == 0 {c = 1; system("cat MyOtherBestAnimals.txt") }; {print} ' \
BestAnimals.txt
This answer can basically be broken down as follows, because ;
separates the awk condition-action pairs:
/cat/ && c == 0 { c = 1; ... }
sets c
to 1 at the first row containing cat. The commands put at the ...
are then executed, but only once, because c
is 1 now.{print}
is the action print with no condition: prints any input line. This is done after the above condition-action pair.Depending on what is actually at the ...
, giraffe is printed, or the contents of "MyOtherBestAnimals.txt" is sent to the standard output, before printing the first line containing "cat".
Edit
After analysis of @glenn jackman's solution, it seems this solution can still be improved: when using input file
nyan cat
cat
the data is appended before nyan cat
and not before the line equal to cat
. The solution is then to request the full line to be equal to cat
:
awk '$0 == "cat" && c == 0 {c = 1; print "giraffe"}; {print}' \
BestAnimals.txt
for the insertion of a single line and
awk '$0 == "cat" && c == 0 {c = 1; system("cat MyOtherBestAnimals.txt") }; {print} ' \
BestAnimals.txt
for the insertion of a file
I would:
grep
to find the line number of the first matchhead
to get the text leading up to the matchcat
tail
to get the lines after the matchIt's neither quick, efficient nor elegant. But it's pretty straight-forward, and if the file isn't gigantic and/or you need to do this many times a second, it should be fine.
If using gnu sed:
$ cat animals
dog
cat
dolphin
cat
$ sed "/cat/ { N; s/cat\n/giraffe\n&/ }" animals
dog
giraffe
cat
dolphin
cat
&
represent the matched string.If you know (or somehow find out) the line:
sed -n '/cat/=' BestAnimals.txt
You can use sed:
sed -i '2i giraffe' BestAnimals.txt