awk“if”声明

时间:2012-12-01 17:38:01

标签: awk

我有一个文件

foo
--
bar

我只想要分隔符上方的行。我已经在这方面挣扎了太长时间,并尝试了许多变种。我的一个班轮是:

echo -e "foo\n-- \nbar" | gawk -v x=0 -- '/^--\ / { x++ } ; IF (x==0) {print} '

这应该只打印“foo”,但我得到整个文件输出。如果我改为打印x,我会

0
1
1

我似乎无法使awk根据x的值有条件地打印一行。我知道我错过了一些简单的事情。

4 个答案:

答案 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'

您可以使用sputnickanswer显示的命令在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