使用 sed 删除分隔符之间的字符串或段落

使用 sed 删除分隔符之间的字符串或段落

我想知道谁要删除(((字符串之间的字符串或段落)))

Lorem ipsum (((dolor sat amet))),consectetur adipiscing elit。 Vestibulum aliquet fringilla est, dictum tempor nunc venenatis at. sed nec velit sat amet velit cursus imperdiet。 Vivamus tincidunt ut nunc quis euismod。 Quisque 坐在 amet lorem rhoncus、malesuada justo at、ullamcorpererat。

所以“dolor sat amet”不应该出现在返回中

这是我现在拥有的命令,它检测到第一个(((,然后停止......

sed -e "/(((/,/)))/d" file.txt

答案1

sed -e :p -e '/(((/!b     
'   -e :n -e 's/)))/\     
/;            s/(((.*\n//; tp
$d;N;         s//(((/;     tn'

这应该可以做到。它会b逃走(因此自动打印)任何不匹配的行(((,但一旦找到,它就会尝试删除第一个出现的(((序列和第一个出现的之间的所有内容)))。如果因为)))在当前行上找不到尾随而不能,则它会拉入Next 行,删除(((和下一行的头部之间的所有内容,然后再次搜索。如果它$在仍在搜索的同时到达最后一行的末尾,则)))它会放弃。通过这种方式,它一次不会缓冲超过一行,因为(((每次必须拉入换行符时,它都会删除后面的所有内容。

它应该处理一条线上可能出现的尽可能多的对 - 并且两端之间是否出现或((( )))并不重要- 它将寻找超过 2 个或更少以及任意数量的。())(

找到后,)))它会重置为搜索(((,因此即使在跨越换行边界后,它也不会无法处理下一对。

  1. :p- 声明p分支标签。如果脚本可以)))用换行符替换序列,则脚本会在此处分支,然后删除(((和之间的所有内容\n
  2. /(((/!b-远离 - 并自动打印模式空间 - 如果模式空间中b没有剩余序列。(((
  3. :n-声明分支:标签n。如果(((找到 a 但)))在同一行上找不到a ,则脚本在此分支。
  4. s/)))/\n/-)))用第一次出现的 替换换行符。仅当 a(((已匹配时才会发生这种情况。
  5. s/(((.*\n//- 替换模式空间中第一行(((和唯一一行之间的所有内容。\n
  6. tp-t预计成功替换;如果为 true,则分支到 label :p
  7. $d;N- 上次替换不成功;如果当前行是$最后一个d元素,否则将Next 附加到模式空间。
  8. s//(((/;tn- 重复最后一个正则表达式,并替换第一次出现的(((和刚刚添加的换行符之间的所有内容,(((然后分支到标签:n

答案2

对单行字符串执行此操作非常简单:

sed 's/((([^)]*)))//g' file

如果您需要它处理多行字符串,它会变得更加复杂。一种方法是使用tr空字符 ( \0) 替换所有换行符,进行替换并再次翻译回来:

tr '\n' '\0' < file | sed 's/((([^)]*)))//g' | tr '\0' '\n'

或者,您可以只使用perl

perl -0pe 's/\(\(\([^)]+\)\)\)//g;' file

-0perl整个文件读入内存的原因(这对于大文件可能是一个问题),意味着“-p打印每一行”,但由于-0,“行”实际上是整个文件。与s///的想法相同sed

答案3

尝试

sed 's/((([^)]*)))//' file

或者在你的句子中可能更好

sed 's/ ((([^)]*)))//' file

相关内容