我正在尝试拆分文件。 sed
可用于执行此操作,例如
sed -e '0,/expr/d' filename
会在“expr”之后给出文件的下半部分但是如果有多次出现并且我想在第n次出现之后拆分怎么办?我想在第二次出现之后是否需要它
sed -e '0,/expr/! {/expr/,$d}' filename
将文件的上半部分提供到“expr”的第二个匹配项。感叹号(!)告诉它忽略第一个范围,只将大括号中的命令应用到文件的其他部分。
但更一般的情况呢?例如,从最后一次出现。
我一直在这里使用sed
,但我认为awk
也会有优雅的解决方案。
答案 0 :(得分:2)
简单的awk解决方案:
直至并包括$n
的{{1}}匹配:
/regex/
最多但不包括awk -vn=$n '{print}/regex/&&!--n{exit}'
匹配:
$n
在上述两个程序中,将n设置为0将打印整个文件。此外,awk -vn=$n '/regex/&&!--n{exit}{print}'
的两种用法都可以更改为{print}
,因为默认操作为1;
。 (或者只是第二个程序中的{print}
。)
为了完整性:
1
匹配后的所有内容:
$n
注意:正如@ mklement0的评论所指出的,在BSD Awk版本中有一个命令行选项解析的错误(又名“one-true-awk”,编写的版本,据我所知仍然由Brian Kernighan维护)2010年5月23日之前;这显然包括随Mac OS X一起发布的版本(截至v10.9)。因此,如果您使用其中一个awk版本,则需要编写awk -vn=$n 'n<=0;/regex/{--n}'
而不是-v n=$n
。
答案 1 :(得分:2)
除了 @rici 的解决方案之外,还有awk
的更多变体
直至并包括$n
匹配:
awk -v n=$n 'p<n; /regex/{p++}' file
最多但不包括$n
匹配:
awk -v n=$n '/regex/{p++} p<n' file
包括$n
匹配
awk -v n=$n '/regex/{p++} p>=n' file
来自且不包括$n
匹配
awk -v n=$n 'p>=n; /regex/{p++}' file
但更一般的情况呢?例如,从倒数第二个 发生。
在这种情况下,简单的方法是使用tac
读取文件反向,执行上述选项并反向再次打印。
包括$n
最后一场比赛
tac file | awk -v n=$n 'p<n; /regex/{p++}' | tac
从最后一场比赛开始,不包括$n
tac file | awk -v n=$n '/regex/{p++} p<n' | tac
最后一场比赛<{1}}
$n
最后一次不包括tac file | awk -v n=$n '/regex/{p++} p>=n' | tac
最后一场比赛
$n
OS X用户注意,如 @ mklement0 在评论中指出
糟糕的[股票] OS X用户(从OS X 10.9开始)运气不好:那里没有tac file | awk -v n=$n 'p>=n; /regex/{p++}' | tac
。
您可以使用tac
(请注意,Linux上的tail -r
似乎不支持tail
)。
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -nr 'x;/^X{2}/{x;p;b};x;/REGEXP/{x;s/^/X/;x}' file
这将在REGEXP
的第二场比赛后打印出任何内容。
N.B。REGEXP
每行可能会出现一次或多次,但只会被计算一次。