SED:删除两个字符串之间的文本,在整行中重复

时间:2015-01-19 10:03:58

标签: bash sed

问题是我希望使用SED删除一行上的所有文本。我理解使用:sed -i 's/str1.*str2//' file.dat删除str1和str2之间的文本,包括str1和str2,但是我的行在行上重复了str1和str2多次,我想删除每个文本之间的文本对。我上面的尝试删除了str1的第一个实例和str2的最后一个实例之间的所有文本。在理解执行此操作的功能时会感谢一些帮助。

另外我想在文件的所有行中重复此操作,并且不知道str1,str2对出现在每一行上的次数。它各不相同。

亲切的问候

附加编辑 - 希望不要进入火焰墙!

可以使用一个例子;到目前为止,很难理解答案。抱歉。

对于example.dat文件中的单行;

bla.bla.TextOfUnknownLength.bla.bla 1023=3 290=1 336=17 273=07:59:57.833 276=K 278=0 bla.bla.TextOfUnknownLength.bla.bla 1023=20 290=2 336=7 273=07:59:57.833 276=K 278=0 bla.bla.TextOfUnknownLength.bla.bla ...

我希望在所有情况下从1023 =删除278 =包含(但不是在278 =之后的0),1023 =和278 =之间的文本可以在一行中多次出现并且长度未知。

文件中还有很多行,我想在所有行中运行它。

HS

3 个答案:

答案 0 :(得分:2)

sed -ri 's/(foo)(.*)(bar)/\1\3/g' between.file

解释。使用正则表达式-r来匹配行中之前,之间和之后的部分。然后使用带有前导反斜杠的sed内部替换变量替换为前缀\1和后缀\2

<强>更新 考虑between.file包含以下内容。

foo---1---bar
foo---2---bar
foo---3---bar

然后上面的命令删除foobar之间的内容,因此输出看起来像

foobar
foobar
foobar

您的文件中所需的输出/更改是不是?

更新:我认为awk更合适 满足您的需求。

假设beween.file包含以下行

A foo---1---bar B foo---10--bar C 
A foo---2---bar D foo---20--bar E 
A foo---3---bar B foo---30---bar C 

此脚本

#!/bin/bash
awk '{                            
                 all="";
                 for(i=0; i<=NF; i++) { 
                   if(!($i~/foo.*bar/)) { all=all" "$i; } 
                 };                            
                 print all;
               }' between.file

将产生以下输出

 A B C
 A D E
 A B C

您可以使用它来实现某种DFA,以便在读取1023时切换到特定状态=并将此读数保留为278 =。

将输出重定向到新文件或搜索documentmantation for awk以直接处理文件。希望这有帮助。

答案 1 :(得分:0)

只需在你的sed结束时添加g

sed -i 's/str1.*str2//g' file.dat 
  • g表示:对于当前缓冲区中的每个出现,默认情况下,这是当前行。
  • 默认情况下,一次只能使用1行,然后在操作结束时继续使用下一行。

备注:

  • 如果str1和str2不在同一条线上,那么2
  • 之间没有变化
  • str1和str2是模式的一部分,因此有时需要转义某些特殊字符(例如(,{,[,\,&,^,.,..,具体取决于所需行为。

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -r ':a;s/([^\n]*)(foo)[^\n]+(bar)/\1\n\2\3/;ta;s/\n//g' file

使用贪婪,一个唯一的分隔符和一个循环来删除foobar之间的字符。贪婪通过线向后工作,分隔符停止已经处理的线的部分再次被处理。该循环删除了foobar的一次或多次出现。