搜索pattern,然后对pattern后面的每个空行进行计数,直到找到第3个空行;然后我想在该空行中放置一个逗号和分号。空行之间可能有大量数据,或者空行之间只有一行文本。
GROUP DIRECTORY CATEGORIES
datadata
Grouping Cat
datadata
datadata
this is the 3rd blank line
我已尝试以下操作但没有成功。有什么建议么?
sed '/GROUP DIRECTORY CATEGORIES/,/^$/^$/^$/,;/' file1>file2
sed '/GROUP DIRECTORY CATEGORIES/$/$/$/,;/' file1>file2
sed '/GROUP DIRECTORY CATEGORIES/{$;$;$/./,;/1;}' file1>file2
答案1
虽然sed
可以用于此目的,但是使用 可以更轻松地完成任何涉及计数的事情awk
。
让我们考虑这个测试文件:
$ cat file1
GROUP DIRECTORY CATEGORIES
datadata
Grouping Cat
datadata
datadata
Above is 3rd blank line
要将 a 添加,;
到之后的第三个空行GROUP DIRECTORY CATEGORIES
:
$ awk '/GROUP DIRECTORY CATEGORIES/{f=1} f && /^$/ {f++; if (f==4) $0=",;"} 1' file1
GROUP DIRECTORY CATEGORIES
datadata
Grouping Cat
datadata
datadata
,;
Above is 3rd blank line
怎么运行的:
/GROUP DIRECTORY CATEGORIES/{f=1}
每当找到与 regex 匹配的行时
GROUP DIRECTORY CATEGORIES
,变量f
就会设置为 1。f && /^$/ {f++; if (f==4) $0=",;"}
如果
f
不为零且当前行为空白,/^$/
则加f
一。如果f
是 4,则将当前空行替换为,;
。1
1
是 awk 的 print-the-line 的神秘简写。
答案2
从根本上讲,您的方法失败了,因为您的表达式每次仅将一行读入其模式空间 - 因此它永远无法匹配多个空行(即使您可以构造适当的正则表达式)。
然而它是可以使用N
循环中的命令将多行读入模式空间。除了 GNU sed 的多行修饰符之外,换行符在多行模式空间中表示为\n
序列 - 因此要测试空行,您需要使用\n\n
而不是^$
.例如:
sed -E '
/GROUP DIRECTORY CATEGORIES/ {
:a # label the start of a loop
$!N # if not at the end of file, read & append the next line
s/((\n\n.*){2})\n\n/\1\n,;\n/ # match and capture 2 instances of successive newlines,
# followed by a 3rd; if found, replace the 3rd by \n,;\n
t # branch out of the loop on successful replacement
ba # else branch back to label 'a'
}' file1
在 GNU sed 中,该t;ba
序列可以替换为Ta
。
答案3
这种复杂的寻址要求正是ex
(or vi
) 真正发挥作用的地方。
ex
是一个POSIX 指定工具vi
这是(“可视化编辑器”)的前身。值得注意的是,所有 -style 命令在 Vim 中ex
仍然可用。vi
在或 Vim 中,假设您想要从文档开头开始vi
第一个实例,您可以按如下方式执行此操作:/pattern/
vi file.txt
通过键入并按在命令行上打开文件<Enter>
键入以下内容,包括前导冒号。然后按
<Enter>
。:0/GROUP DIRECTORY CATEGORIES//^$//^$//^$/s/^/,;/
:x
键入并按 来保存更改<Enter>
。
在上面的命令中,小写之前的所有内容s
都只是一个地址。该s
命令应该非常明显。
地址的意思是,“从文件的最开始(行‘0’)开始,‘GROUP DIRECTORY CATEGORIES’的第一个实例,从那里开始一个空行的第一个实例,然后是一个空行的下一个实例,然后是下一个,然后运行替代命令。”
还有很多其他方法可以将其分开;它不一定是单衬。
您还可以使用以下ex
命令完成此编辑:
0/GROUP DIRECTORY CATEGORIES/
/^$/
//
//
s//,;/
x