使用 Bash 在某一行之前插入文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12248784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:10:50  来源:igfitidea点击:

Insert text before a certain line using Bash

bashshell

提问by Pez Cuckow

How can I insert a set of lines (about 5) into a file at the first placea string is found?

如何在找到字符串的第一个位置将一组行(大约 5 行)插入到文件中?

For example:

例如:

BestAnimals.txt

最佳动物.txt

dog
cat
dolphin
cat

$ "Insert giraffe to BestAnimals.txt before cat" > NewBestAnimals.txt

$ "在 cat 之前将长颈鹿插入 BestAnimals.txt" > NewBestAnimals.txt

NewBestAnimals.txt

NewBestAnimals.txt

dog
giraffe 
cat
dolphin
cat

回答by Fredrik Pihl

If using gnu sed:

如果使用 gnu sed:

$ cat animals
dog
cat
dolphin
cat

$ sed  "/cat/ { N; s/cat\n/giraffe\n&/ }" animals
dog
giraffe
cat
dolphin
cat
  1. match a line with (/cat/)
  2. continue on next line (N)
  3. substitute the matched pattern with the insertion and the matched string, where &represent the matched string.
  1. 与 (/cat/) 匹配一行
  2. 在下一行继续 (N)
  3. 用插入和匹配的字符串替换匹配的模式,其中&表示匹配的字符串。

回答by glenn Hymanman

awk -v insert=giraffe -v before=cat '
   == before && ! inserted {
    print insert
    inserted++
  }
  {print}
' BestAnimals.txt > NewBestAnimals.txt

回答by j0nes

If you know (or somehow find out) the line:

如果您知道(或以某种方式找出)该行:

sed -n '/cat/=' BestAnimals.txt

You can use sed:

您可以使用 sed:

sed -i '2i giraffe' BestAnimals.txt

回答by bernard paulus

An awk solution:

一个awk解决方案:

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

如果您要插入的动物在“MyOtherBestAnimals.txt”中,您也可以这样做

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:

这个答案基本上可以分解如下,因为;分开了 awk 条件-动作对:

  • /cat/ && c == 0 { c = 1; ... }sets cto 1 at the first row containing cat. The commands put at the ...are then executed, but only once, because cis 1 now.
  • {print}is the action print with no condition: prints any input line. This is done after the above condition-action pair.
  • /cat/ && c == 0 { c = 1; ... }c在包含 cat 的第一行设置为 1。...然后执行放在 的命令,但只执行一次,因为c现在是 1。
  • {print}是没有条件的操作打印:打印任何输入行。这是在上述条件-动作对之后完成的。

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".

...在打印包含“cat”的第一行之前,根据实际的内容,打印长颈鹿,或者将“MyOtherBestAnimals.txt”的内容发送到标准输出。

Edit

编辑

After analysis of @glenn Hymanman's solution, it seems this solution can still be improved: when using input file

分析@glenn Hymanman的解决方案后,看来这个解决方案还可以改进:使用输入文件时

nyan cat
cat

the data is appended before nyan catand not before the line equal to cat. The solution is then to request the full line to be equal to cat:

数据附加在nyan cat等于 的行之前而不是之前cat。然后解决方案是请求整行等于cat

awk '
awk '##代码## == "cat" && c == 0 {c = 1; system("cat MyOtherBestAnimals.txt") }; {print} ' \
     BestAnimals.txt
== "cat" && c == 0 {c = 1; print "giraffe"}; {print}' \ BestAnimals.txt

for the insertion of a single line and

用于插入单行和

##代码##

for the insertion of a file

用于插入文件

回答by unwind

I would:

我会:

  1. Use grepto find the line number of the first match
  2. Use headto get the text leading up to the match
  3. Insert the new content using cat
  4. Use tailto get the lines after the match
  1. 使用grep找到的第一个匹配的行号
  2. 使用head来获取文本导致对比赛
  3. 使用插入新内容 cat
  4. 使用tail得到赛后线

It'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.

它既不快速、高效也不优雅。但它非常简单,如果文件不是很大和/或您需要每秒多次执行此操作,应该没问题。