使用sed,当在两个模式中找不到另一个模式时,如何在两个模式之间添加文本?
使用sed,当在两个模式(此处使用sed,当在两个模式中找不到另一个模式时,如何在两个模式之间添加文本?,sed,Sed,使用sed,当在两个模式(此处Pattern\u one和Pattern\u two)之间找不到另一个模式(此处Pattern\u interest)时,如何在其中添加文本(例如此处Inserted\u text) 在我的文件中,行尾字符只是一个\n(即Unix格式),但我在msdos下使用GNU版本4.0.7 我尝试过但无效的命令: sed -i ":a;N;$!ba;/\nPattern_one/ /\nPattern_of_interest/! /\nPattern_two/ a/Inse
Pattern\u one
和Pattern\u two
)之间找不到另一个模式(此处Pattern\u interest
)时,如何在其中添加文本(例如此处Inserted\u text
)
在我的文件中,行尾
字符只是一个\n
(即Unix格式),但我在msdos下使用GNU版本4.0.7
我尝试过但无效的命令:
sed -i ":a;N;$!ba;/\nPattern_one/ /\nPattern_of_interest/! /\nPattern_two/ a/Inserted_text/" file.txt
这些模式都是从一行的开头开始的
下面例子中的“blabla”可以是任何东西
输入文件的示例:-
blabla
blabla
Pattern_one
Pattern_of_interest blabla
blabla
Pattern_two
blabla
blabla
blabla
blabla
Pattern_one
Pattern_two
blabla
blabla
blabla
Pattern_one
blabla
blabla
Pattern_two
blabla
blabla
所需的输出文件(插入在顶部、下方、图案旁边):
所需的输出文件(底部插入,iow,图案二旁边):
我需要在顶部插入,但如果您也能告诉我如何在底部插入,那也很好。它就在那里:
而且oldfile.txt
和file.txt
之间有区别:
diff -W 60 -y oldfile.txt file.txt
blabla blabla
blabla blabla
Pattern_one Pattern_one
Pattern_of_interest blabla Pattern_of_interest blabla
blabla blabla
Pattern_two Pattern_two
blabla blabla
blabla blabla
blabla blabla
blabla blabla
Pattern_one Pattern_one
> Inserted_text
Pattern_two Pattern_two
blabla blabla
blabla blabla
blabla blabla
Pattern_one Pattern_one
> Inserted_text
blabla blabla
blabla blabla
Pattern_two Pattern_two
blabla blabla
blabla blabla
如果你更喜欢在模式二之前有自己的兴趣模式:
。。。然后diff变成:
blabla blabla
blabla blabla
Pattern_one Pattern_one
Pattern_of_interest blabla Pattern_of_interest blabla
blabla blabla
Pattern_two Pattern_two
blabla blabla
blabla blabla
blabla blabla
blabla blabla
Pattern_one Pattern_one
> Inserted_text
Pattern_two Pattern_two
blabla blabla
blabla blabla
blabla blabla
Pattern_one Pattern_one
blabla blabla
blabla blabla
> Inserted_text
Pattern_two Pattern_two
blabla blabla
blabla blabla
另一种方法,无需将整个块存储在内存中
但这种方式意味着在块的末尾添加插入的文本:
sed -e '
/Pattern_one/,/Pattern_two/{
//{
/one/h;
/two/{
x;
/Pattern_of_interest/!iInserted_text
x;
};
};
/Pattern_of_interest/h;
}' -i file.txt
sed的另一种方法:
sed '/Pattern_one/{:a;N;/Pattern_two/!ba;/Pattern_of_interest/! {/Pattern_one/s/\n/&Inserted_text\n/};P;D;}' file
将Pattern\u one
和Pattern\u two
之间的行添加到模式空间,如果块中找不到感兴趣的Pattern\u
,请在Pattern\u one
之后插入新文本
要在模式二之前插入文本,请执行以下操作:
sed '/Pattern_one/{:a;N;/Pattern_two/!ba;/Pattern_of_interest/! {/Pattern_two/s/.*\n/&Inserted_text\n/};P;D;}' file
sed '/Pattern_one/!b;:a;N;/Pattern_two/!ba;/Pattern_of_interest/b;h;s/\n[^\n]*$//p;x;s/^.*\n//;iInserted text' file
这可能适用于您(GNU-sed):
使用Pattern\u one
查找地址,否则按正常方式打印(无需进一步处理)
引入一个位置:a
,并使用N
命令将下一行追加到模式空间(PS)
检查PS是否包含地址模式\u two
,如果不包含,则返回位置:a
,然后重复
PS现在包含从Pattern\u one
到Pattern\u two
的所有行
检查PS,查看它是否包含感兴趣的图案
,以及它是否爆发b
,并正常打印,在此循环中不进行进一步处理
如果没有,请使用h
命令将PS复制到保留空间(HS),然后使用替换命令s/\n.*//p
,打印PS的第一行
使用命令x
将HS替换为PS,并使用另一个替换命令s/^[^\n]*\n/
准备PS以包含减去第一行的剩余行
现在使用i
命令插入新文本
执行插入命令后,sed循环将打印PS中剩余的内容
用于在模式二之前插入文本:
sed '/Pattern_one/{:a;N;/Pattern_two/!ba;/Pattern_of_interest/! {/Pattern_two/s/.*\n/&Inserted_text\n/};P;D;}' file
sed '/Pattern_one/!b;:a;N;/Pattern_two/!ba;/Pattern_of_interest/b;h;s/\n[^\n]*$//p;x;s/^.*\n//;iInserted text' file
除了末尾的两个替换命令外,它使用基本相同的代码首先打印PS中最后一行的所有行,然后在执行插入命令后将PS准备为仅包含最后一行。我认为这更适合
awk
,你有这个命令吗?@Sundeep我经常使用block和underblock来研究和治疗!请看@F.Hauri,这只会强化我的观点,awk
更适合。。。那个代码对我来说是希腊语,我过去曾试图理解它,但无法。。对我来说(对大多数其他人来说也是如此),将perl/awk与更常用的编程流程结合使用更容易@Sundeep:我同意你的观点,awk脚本更容易处理。通常,我依靠sed对存储在纯文本中的从头开始的数据提取进行预格式化,然后在插入字段和记录分隔符时使用awk处理文件。这样,您就无法选择将插入的文本放置在块的第一行。如果您不想将整个块存储在内存中,我添加了另一种方法,即无论如何使用块。@F.Hauri I edited。第一个命令是在模式一
之后插入新文本,第二个命令是在模式二
之前插入新文本。
sed '/Pattern_one/{:a;N;/Pattern_two/!ba;/Pattern_of_interest/! {/Pattern_two/s/.*\n/&Inserted_text\n/};P;D;}' file
sed '/Pattern_one/!b;:a;N;/Pattern_two/!ba;/Pattern_of_interest/b;h;s/\n.*//p;x;s/^[^\n]*\n//;iInserted text' file
sed '/Pattern_one/!b;:a;N;/Pattern_two/!ba;/Pattern_of_interest/b;h;s/\n[^\n]*$//p;x;s/^.*\n//;iInserted text' file