我尝试在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的最后一行,然后在它之后添加一个新行。
感谢任何帮助。
答案 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
}'
<强>解释强>
答案 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