我正在使用bash,并希望使用单行直接在文件中应用更改,因此sed将是完美的。
我尝试使用sed选项N然后搜索“\ n {3,}”并将其替换为“\ n \ n”,但这不起作用...
sed -ri 'N;N;N;N;s/^(\n){3,}$/\n\n/' ./file
此外,这不会考虑所有搜索模式的出现,因为它必须要求自己起作用。
答案 0 :(得分:1)
经过一些实验,我想出了以下内容:
/./n # non-empty line; just print it as normal
N # otherwise, append the next line
/^\n$/D # and if it's also empty, delete the first line, and don't print yet
我正在使用GNU sed,当你最后使用N
时它不会退出;对于其他实现,您可能需要$!N
。
您可以通过在最终命令中添加更多\n
个字符来轻松调整允许的最大空行数。
这是一个测试,显示它在文件的开头,中间和结尾处起作用:
$ echo $'\n\nabc\n\ndef\n\n\n\n\nabc\n\n\n' | sed -e '/./n;N;/^\n$/D'
abc
def
abc
$
答案 1 :(得分:0)
我不确定这正是您所寻找的,但如果没有,它应该指向正确的方向:
sed -n '/./!H;/./{x;s/\n\{3,\}//p;x;p}'
如果该行为空,请将其放入保留空间。如果该行不为空,则交换模式并保留空间,删除不需要的换行符并打印前一个保留空间。然后从保留空间中取出非空行并打印出来。
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed '/^$/n;//!b;:a;N;s/\n$//;ta' file
如果当前行为空,则打印它并使用下一行刷新。如果当前行不为空,请将其打印并重新开始。如果当前行为空,则删除任何其他空行,直到非空行或文件结尾。
答案 3 :(得分:-1)
根据您的要求,Sed很难保持兼容。但是,既然你只想要一个内衬,那么perl就可以完成这项工作并且可能更便携
如果您需要两个空白行(文本之间有3个换行符):
perl -p0777i -e 's/^\n{3,}/\n\n/; s/\n{4,}/\n\n\n/sg;' yourfile.txt
如果您需要一个空白行(文本之间有2个换行符):
perl -p0777i -e 's/^\n{2,}/\n/; s/\n{3,}/\n\n/sg;' yourfile.txt
如果您需要一个空白行,但文件开头没有换行符:
perl -p0777i -e 's/^\n+//; s/\n{3,}/\n\n/sg;' yourfile.txt
如果你不特别关心文件开头是否有一两个空白:
perl -p0777i -e 's/\n{3,}/\n\n/sg;' yourfile.txt
测试脚本:
#!/bin/bash
test_contents()
{
cat <<EOF
3 blank lines 3 linefeeds prior, expect 1 removed
3 blank lines 4 linefeeds after, expect 1 removed
1 blank line, 2 linefeeds after, expect no change
2 blank line, 3 linefeeds after, expect no change
5 blank lines, 6 linefeeds after, expect 3 removed
3 lines to end of file, expect 1 removed
EOF
}
before=$(mktemp -t test_before.XXXXXX)
after=$(mktemp -t test_after.XXXXXX)
sed_after=$(mktemp -t test_sed.XXXXXX)
test_contents > "${before}"
test_contents > "${after}"
test_contents > "${sed_after}"
perl -p0777i -e 's/^\n{3,}/\n\n/; s/\n{4,}/\n\n\n/sg;' "${after}"
echo Orig:
cat "${before}"
echo "Diff:"
diff -U1000 "${before}" "${after}"
这是做什么的:
-p0777 read whole files in one go
-i edit files specified on commandline
-e specify the edit expression
表达式参数/ sg
的意思是:
s - treat as a whole string including newlines
g - keep applying the edits until no more can be done
输出是:
+ diff -U1000 /tmp/test_before.XSRHYr /tmp/test_after.mU4hLU
--- /tmp/test_before.XSRHYr 2017-02-14 21:31:09.376110847 +1030
+++ /tmp/test_after.mU4hLU 2017-02-14 21:31:09.379110855 +1030
@@ -1,23 +1,17 @@
-
3 blank lines 3 linefeeds prior, expect 1 removed
3 blank lines 4 linefeeds after, expect 1 removed
-
1 blank line, 2 linefeeds after, expect no change
2 blank line, 3 linefeeds after, expect no change
5 blank lines, 6 linefeeds after, expect 3 removed
-
-
-
3 lines to end of file, expect 1 removed
-