我有一个文件
foo
--
bar
我只想要分隔符上方的行。我已经在这方面挣扎了太长时间,并尝试了许多变种。我的一个班轮是:
echo -e "foo\n-- \nbar" | gawk -v x=0 -- '/^--\ / { x++ } ; IF (x==0) {print} '
这应该只打印“foo”,但我得到整个文件输出。如果我改为打印x,我会
0
1
1
我似乎无法使awk根据x的值有条件地打印一行。我知道我错过了一些简单的事情。
答案 0 :(得分:4)
尝试这样做:
echo -e "foo\n-- \nbar" | awk '/^--/{exit}1'
<强>说明强>
/^--/
是匹配当前行开头字符串的正则表达式{}
部分在条件为 true (前一个正则表达式)时执行1
与{print}
类似:默认情况下,如果条件为 true ,则会在STDOUT上打印awk
。虽然awk的1
true ,但它会打印当前行。分解命令:
echo -e "foo\n-- \nbar" | awk '
{
if (/^--/) {
exit
}
else {
print
}
}
'
替代分解:
echo -e "foo\n-- \nbar" |
awk '(/^--/) { exit }
{ print }'
这强调有两种模式行为规则;一个具有显式模式和退出动作;另一个是隐式模式和打印动作。
答案 1 :(得分:2)
如果您更喜欢sed
:
sed -n '/^--$/q;p' file.txt
说明:sed
逐行读取文件。如果sed找到模式^--$
(即,包含完全--
的行),则退出(这是q
命令),否则,sed
打印出该内容line(使用p
命令)。请注意sed
是使用-n
选项启动的,即除非使用p
命令明确告知,否则不会输出任何内容。由于sed
在找到分隔符--
时退出(即在p
命令之前),因此不会打印此分隔符。
关于sed
的好处是,它比awk
更快地执行此任务。
编辑。正如glenn jackman在评论中指出的那样,使用GNU sed,你可以使用:
sed '/^--$/Q' file.txt
(当我回答时,我没有在sed
上使用Q
命令的计算机上。谢谢glenn。
答案 2 :(得分:1)
你的原始剧本是正确的,但太复杂了:
echo -e "foo\n-- \nbar" | gawk '/^--\ / { x++ } { if (x==0) print}'
变量由awk
自动创建并归零(因此您不需要-v x=0
等)。 “发现双击”代码很好。分号是不必要的(充其量)。 IF (x == 0) {print}
显然很奇怪。 Mac OS X 10.7.5上的awk
接受了它,但我不确定它在做什么。替换操作适用于每一行,并在打印前测试x
是否为零。
就个人而言,我可能会使用sed
:
echo -e "foo\n-- \nbar" | sed '/^--/q'
将sed
命令修改为gniourf_gniourf suggests:
echo -e "foo\n-- \nbar" | sed -n '/^--/q;p'
您可以使用sputnick中answer显示的命令在awk
中模仿该内容。
echo -e "foo\n-- \nbar" | awk '/^--/ {exit} 1'
1匹配每一行(它始终为true)并触发默认操作,即'print $ 0'。你也可以写:
echo -e "foo\n-- \nbar" | awk '/^--/ {exit} {print}'
答案 3 :(得分:1)
在GNU awk中,您可以将记录分隔符设置为仅包含“ - ”的行,然后只打印第一条记录:
$ gawk -v RS='\n--\n' 'NR==1' file
foo
或表现是一个问题:
$ gawk -v RS='\n--\n' 'NR==1{print;exit}' file
foo
通过这种方式,您可以稍后增强脚本以打印您可能需要的任何其他记录:
$ cat file
the
quick
--
brown
fox
--
jumped
$
$ gawk -v RS='\n--\n' 'NR==1' file
the
quick
$ gawk -v RS='\n--\n' 'NR==2' file
brown
fox
$ gawk -v RS='\n--\n' 'NR==3' file
jumped