在bash中最后一次出现字符串后插入新行

时间:2014-08-29 11:27:20

标签: bash awk sed newline

我尝试在bash中最后一次出现字符串后添加新行。

例如,如果我有以下文字:

GG1 test-35
GG1 test-38
GG1 test-40

HH1 test-52
HH1 test-60
HH1 test-32
HH1 test-40

LL1 test-101
LL1 test-99
LL1 test-24

说我想在' HH'的末尾添加一个新行。阻止,所以它变成:

HH1 test-52
HH1 test-60
HH1 test-32
HH1 test-40
HH1 test-56

到目前为止,我已经尝试过使用sed和awk,但似乎无法做到正确。如果我可以搜索一个实际的测试号码,比如HH1 test-40,这很简单,但我唯一可以搜索的是首字母缩略词。所以我需要HH1的最后一行,然后在它之后添加一个新行。

感谢任何帮助。

7 个答案:

答案 0 :(得分:3)

快速&肮脏的gawk:

 awk 'BEGIN{RS="";ORS="\n\n"}/^HH/{$0=$0"\nHH1 test-56"}7' file

它很脏,因为它在输出结束时留下一个空行。

答案 1 :(得分:1)

有很多选择:

awk '/HH/{seen++} seen && !/HH/{print "HH1 test-56"; seen=0} 1' file

或:

tac file | awk '/HH/ && !seen{print "HH1 test-56"; seen++} 1' | tac

或:

awk 'NR==FNR{if (/HH/) nr=NR; next} 1; FNR==nr{print "HH1 test-56"}' file file

或(gawk-only for multi-char RS):

gawk -v RS='^$' -v ORS= '{sub(/.*HH[^\n]+\n/,"&HH1 test-56\n")} 1' file

...或

答案 2 :(得分:1)

还有一个问题 应该适用于所有问题

awk 'a=/^HH/{b=1}b&&!a{print "HH1 test-56";b=0}1' file

awk -F- 'a=/HH/{b=$1}b&&!a{print b"-56";b=0}1' file

答案 3 :(得分:1)

这可能适合你(GNU sed& Bash):

sed '/^HH1/!b;:a;n;//ba;i\HH1 test-56' file

如果该行没有正常开始HH1打印,则打印直到该行不开始HH1然后插入换行符。

答案 4 :(得分:0)

LineToAdd="HH1 test-56"
{ echo "${LineToAdd}"; cat YourFile; } | sed -n '1x;H;${x
   s/^\([^ ]\{3\}\) \([^[:cntrl:]]*\)\(\n\)\(.*\)\1 \([^[:cntrl:]]*\)\3/\4\1 \5\3\1 \2\3/
   s/^\n//
   p
   }'

<强>解释

  • 在内容开头添加行添加(可以通过添加结束,添加一些代码来完成)
  • 加载缓冲区中的所有行
  • 在第1组的最后一行之后移动(通过重新打印组位置)2组第一行(因此组1为HH1,测试-56为组2)。(假设没有HH1,这里是快速和脏的)在以下一行的内容中)
  • 删除第一行如果是新行(快速和脏也,假设原始文件不以新行开头)
  • 打印结果 -

答案 5 :(得分:0)

以下perl命令会在最后一行HH1后添加一个新行

perl -0777pe 's/(?s)(?<=HH1\stest-)(\d+\n)(?=(?:(?!HH1\stest-).)*$)/\1HH1 test-56\n/' file

示例:

$ cat file
HH1 test-52
HH1 test-60
HH1 test-32

LL1 test-101
LL1 test-99
HH1 test-40
LL1 test-24

$ perl -0777pe 's/(?s)(?<=HH1\stest-)(\d+\n)(?=(?:(?!HH1\stest-).)*$)/\1HH1 test-56\n/' file
HH1 test-52
HH1 test-60
HH1 test-32

LL1 test-101
LL1 test-99
HH1 test-40
HH1 test-56
LL1 test-24

答案 6 :(得分:0)

小的bash脚本还可以提供您正在寻找的灵活性和字符串添加:

#!/bin/bash

## Usage:
#
# ./scriptname datafile [new-sting-to-add (HH1 test-56)] [string-to-search (HH1)]

newstr="${2:-HH1 test-56}"          # set newstr
srchstr="${3:-"${newstr// */}"}"    # set srchstr
found=1                             # set found flag to false

# read datafile line-by-line
while read pfx tststr || [ -n "$tststr" ] ; do
    [ "$pfx" == "$srchstr" ] && found=0                 # if pfx matches set flag
    [ $found -eq 0 ] && [ "$pfx" != "$srchstr" ] && {   # if flag and no match
        echo "$newstr"                                  # add newstr to output
        found=1                                         # reset flag to false
    }
    echo "$pfx $tststr"             # normal output

done <"$1"

<强>输出:

$ ./hh.sh dat/hh.dat    # (using default values)
GG1 test-35
GG1 test-38
GG1 test-40

HH1 test-52
HH1 test-60
HH1 test-32
HH1 test-40
HH1 test-56

LL1 test-101
LL1 test-99
LL1 test-24