![在包含多个 expr2 的文件中,将与 expr1 匹配的行移到另一个与上面 expr2 匹配的行之前](https://linux22.com/image/187476/%E5%9C%A8%E5%8C%85%E5%90%AB%E5%A4%9A%E4%B8%AA%20expr2%20%E7%9A%84%E6%96%87%E4%BB%B6%E4%B8%AD%EF%BC%8C%E5%B0%86%E4%B8%8E%20expr1%20%E5%8C%B9%E9%85%8D%E7%9A%84%E8%A1%8C%E7%A7%BB%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E4%B8%8E%E4%B8%8A%E9%9D%A2%20expr2%20%E5%8C%B9%E9%85%8D%E7%9A%84%E8%A1%8C%E4%B9%8B%E5%89%8D.png)
我有一个包含多个文件的文件夹。在每个文件中,该单词可能会出现一次或多次implicit
,并且在某些文件中implicit
可能会出现use output
几行句子。后 implicit
。一般来说,我不知道有多少行将它们分开。一些示例文件如下所示:
前1.f
...some text...
implicit
...some other text...
前2.f
...some text...
implicit
...a few lines...
use output
...some other text...
前3.f
...some text...
implicit
...a few lines...
use output
...some other text...
implicit
...a few lines...
use output
...some more text...
前4.f
...some text...
implicit
...some other text...
implicit
...few lines...
use output
...some more text...
我想移动所有出现的use output
多于implicit
之前找到的最接近的use output
。
请注意,通常解决方案应不区分大小写。任何基于 grep、sed、awk 的东西都可以。
从概念上讲,我认为解决方案应该遵循以下逻辑:
- 匹配
use output
- 删除该行并保留其内容
- 反转搜索方向并查找第一次出现的
implicit
- 一旦匹配,添加
use output
上面的implicit
行 - 再次反向搜索方向并返回寻找
use output
答案1
如果我们以相反的顺序来看范围问题,它们就会被简化。最后记得再次反转以维持宇宙的和谐。
使用范围运算符,
将最大化正则表达式计数,但会提高可读性。
tac file_name |
sed -e '
/use output/,/implicit/!b
/use output/{h;d;}
/implicit/G
' |
tac ;
无需求助于范围运算符。以代码复杂性为代价最小化正则表达式数量。
tac file |
sed -e '
/use output/!b
$q;h;N;s/.*\n//
:loop
n
/implicit/!bloop
G
' |
tac ;
答案2
如果该tac
实用程序不存在,我们仍然可以在 中执行此操作sed
,但现在我们无法打印,直到我们看到“使用输出”行,因为我们不知道在此之前可能会出现另一个“隐式”行。
sed -n '
/implicit/!bp
h
:loop
${g;bp;}
n
/implicit/{x;p;bloop;}
H
/use output/!bloop
G;s/\n[^\n]*$//
:p;p
' file