4

我有一个文件

foo
--
bar

我只想要分隔符上方的线条。我已经为此苦苦挣扎了太久,并尝试了许多变体。我的一个班轮是:

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

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

0
1
1

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

4

4 回答 4

4

尝试这样做:

echo -e "foo\n-- \nbar" | awk '/^--/{exit}1'

解释

  • /^--/是匹配当前行开头的字符串的正则表达式
  • {}如果条件为,则执行部分(前一个正则表达式)
  • 1就像{print}:默认情况下,awk如果条件为,则在 STDOUT 上打印。虽然对于 awk1正确的,但它会打印当前行。

命令的分解:

echo -e "foo\n-- \nbar" | awk '
    {
        if (/^--/) {
            exit
        }
        else {
            print
        }
    }
'

替代分解:

echo -e "foo\n-- \nbar" |
awk '(/^--/) { exit }
             { print }'

这强调了有两个模式动作规则;具有显式模式和退出操作的一种;另一个具有隐式模式和打印动作。

于 2012-12-01T17:41:37.227 回答
2

如果你sed更喜欢:

sed -n '/^--$/q;p' file.txt

解释:sed逐行读取文件。如果 sed 找到该模式^--$(即,正好包含 的行--)它退出(即q命令),否则,sed打印出该行的内容(使用p命令)。请注意,这sed是使用该-n选项启动的,即除非使用命令明确告知,否则不会输出任何内容p。由于在找到sed分隔符时退出--(即在p命令之前),因此不会打印此分隔符。

好处sed是它比awk这个任务更快。

编辑。正如 glenn jackman 在评论中指出的那样,使用 GNU sed,您可以使用:

sed '/^--$/Q' file.txt

(当我回答时,我不在具有sedwith命令的计算机上)。Q谢谢格伦。

于 2012-12-01T18:00:44.223 回答
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'

按照gniourf_gniourf 的建议修复我的sed命令:

echo -e "foo\n-- \nbar" | sed -n '/^--/q;p'

您可以使用sputnick在他的回答awk中显示的命令来模仿它。

echo -e "foo\n-- \nbar" | awk '/^--/ {exit} 1'

1 匹配每一行(它始终为真)并触发默认操作,即“打印 $0”。你也可以写:

echo -e "foo\n-- \nbar" | awk '/^--/ {exit} {print}'
于 2012-12-01T17:58:12.553 回答
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
于 2012-12-02T14:54:57.947 回答