我有一个进程输出太多带有回车符(\r)的状态行。我可以通过管道过滤所有这些状态行
sed '/\r/d'
相反,我想过滤除每 3 行之外的所有这些行。这可以使用标准 Unix 工具(awk?)还是我需要一个脚本?没有 CR 的行应该保持不变。
给定输出:
$ (printf '%s\n' {1..10}; printf '%s\r\n' {1..10}; printf '%s\n' {1..10};) | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M
1
2
3
4
5
6
7
8
9
10
想要的输出(或任何其他模式):
1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10
答案1
$ awk '!(/\r$/ && ((++c)%3 != 1))' file | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10
原答案:
听起来你需要的就是这个,使用任何 awk:
awk -v RS='\r' '{ORS=(NR%10000 ? "" : RS)} 1'
例如使用它作为输入:
$ printf '%s\r\n' {1..10} | cat -v
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M
删除除每三个之外的所有\r
:
$ printf '%s\r\n' {1..10} | awk -v RS='\r' '{ORS=(NR%3 ? "" : RS)} 1' | cat -v
1
2
3^M
4
5
6^M
7
8
9^M
10
答案2
使用GNU sed
,我们使用保留空间进行计数。
sed -E '
/\r$/{
G;/\n$/P
s/.*\n/./
/.{3}/z;x;d
}
' file
使用awk
,我们使用变量 c 作为循环计数器,当它达到 3 时就会重置。
awk '
!/\r$/ || !c++
c==3{c=0}
' file
假设回车符 ( ) 无论何时出现,都出现在换行符 ( ) 分隔记录的\r
末尾。\n
答案3
这是在 awk 中执行此操作的一种边缘方法:
{m,g}awk '((+$_ % 3) % NF)~(!_<NF)' FS='\r$' # yes that's a
# tilde ~ not a minus -
1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10
表达同一事物的其他方式
mawk 'NF-!_== (+$+_ % 3 ) % NF' FS='\r$'
gawk 'NF-!_== ( $(_++)%(_+_+_--)) % NF' FS='\r$'