【问题标题】:Cut matching line and X successive lines until newline and paste into file剪切匹配行和 X 连续行直到换行并粘贴到文件中
【发布时间】:2019-11-14 20:54:48
【问题描述】:

我想匹配包含一个单词的文件中的所有行,并取下面的所有行,直到连续出现两个两个换行符。

我有以下 sed 代码来剪切和粘贴特定行,但没有后续行:

sed 's|.*|/\\<&\\>/{w results\nd}|' teststring | sed -file.bak -f - testfile

如何修改它以获取所有后续行?

例如,假设我想匹配 'dog' 的行,下面应该取 5 的前 3 行:

The best kind of an animal is a dog, for sure
-man's best friend
-related to wolves

Racoons are not cute

有没有办法做到这一点?

【问题讨论】:

  • @WiktorStribiżew 正则表达式可以匹配,但是如何使用 awk 移动到新文件并从原始文件中删除?
  • @WiktorStribiżew 在这种情况下,我使用 take 表示“剪切”,剪切并粘贴到新文件中。所以这 3 行不会出现在 testfile 中,但会出现在 newfile 中
  • 那么,还没有解决?请编辑问题以包含更多详细信息。

标签: text awk sed gnu


【解决方案1】:

应该这样做:

awk '/dog/ {f=1} /^$/ {f=0} f {print > "new"} !f {print > "tmp"}' file && mv tmp file

如果找到单词dog,它将设置f为true,如果找到一个空行,则将f设置为false。
如果f 为真,则打印到new 文件。
如果f 为假,则打印到tmp 文件。
tmp文件复制到原始文件

编辑:可以缩短一些:

awk '/dog/ {f=1} /^$/ {f=0} {print > (f?"new":"tmp")}' file && mv tmp file

Edit2:根据要求为new 文件中的每个部分添加空间:

awk '/dog/ {f=1;print ""> "new"} /^$/ {f=0} {print > (f?"new":"tmp")}' file && mv tmp file

如果原始文件确实包含制表符或空格,而不是每个狗部分后的空行,请从 /^$/ 更改为 /^[ \t]*$/

【讨论】:

  • 实际上这似乎占用了很多与术语不匹配的行...我该如何帮助解决问题?
  • @JakeRankin Kan 你给出的示例输入不起作用?
  • 我无法提供样本输入。当我在一个大文件(300k 文本文件)上使用时,似乎大多数行都匹配,即使它们不匹配,因为它们最终出现在新文件中。当我使用最后 10 行并进行测试时,它似乎可以正常工作。
  • 有没有办法在每个匹配的部分之后添加换行符/空行并剪切/粘贴到新文件中?
  • @JakeRankin 见edit2。它在新文件的每个部分之前添加一个闪烁线
【解决方案2】:

请您尝试关注一下。

awk '/dog/{count="";found=1} found && ++count<4'  Input_file > temp && mv temp Input_file

【讨论】:

  • @JakeRankin,谢谢杰克。此外,我更改了将输出保存到 Input_file 本身的命令,如果这对您有帮助,请告诉我?
【解决方案3】:

这可能对你有用(GNU sed):

sed 's|.*|/\\<&\\>/ba|' stringFile | 
sed -f - -e 'b;:a;w resultFile' -e 'n;/^$/!ba' file

从 stringFile 构建一组正则表达式并将匹配发送到 :a。然后将匹配的行和任何其他行写入到 resultFile。

注意结果可以直接发送到resultFile,使用:

sed 's#.*#/\\<&\\>/ba#' stringFile |
sed -nf - -e 'b;:a;p;n;/^$/!ba' file > resultFile

要从原始文件中删除匹配项,请使用:

sed 's|.*|/\\<&\\>/ba|' stringFile |
sed -f - -e 'b;:a;N;/\n\s*$/!ba;w resultFile' -e 's/.*//p;d' file

【讨论】:

  • 这是否也会从原始文件中删除匹配行?
  • 哦对不起,要剪切原文件看第三个解决方案
  • 这可能是一个愚蠢的问题,但我不确定该术语在哪里匹配。是代替&lt;&amp; 吗?
  • 要匹配的词放在 stringFile 中,或者你有它 teststring,每行一个,即如果你把 dog 放在第一行,cat 在第二行,那么匹配 dog或 cat 到下一个空白行,将被剪切并粘贴到结果文件中。
  • 啊,我明白了,我有点不确定,谢谢你现在测试
【解决方案4】:

这是你想要做的吗?

$ awk -v RS= '/dog/' file
The best kind of an animal is a dog, for sure
-man's best friend
-related to wolves

【讨论】:

  • 您的解决方案只会测试记录是否包含dog,而不是以dog 开头的行。不确定这是否是 OP 的意图。
猜你喜欢
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多