使用awk选择字符串后面的字段

时间:2014-08-19 05:01:45

标签: awk

对于刚刚在周末介绍它的人来说,我非常陌生。 我有一个问题,我希望有人可以帮助我。

如何选择特定字符串后面的字段?

如何扩展此代码以选择特定字符串后面的多个字段?

例如,对于我的文本文件中的任何给定行,我有类似

的内容
2 of 10 19/4/2014 school name random text distance 800m more random text time 2:20:22 winner someonefast. 

某些属性非常一致,因此我可以轻松提取这些字段。例如2,10和日期。但是,在我希望提取的下一个字段之前,通常会有很多变量文本。因此问题。使用awk可以提取字符串后面的下一个字段吗?例如,我对/ distance /或/ time / string后面的字段以及$ 1,$ 3,$ 4,$ 5感兴趣。

非常感谢您的帮助。

安迪

3 个答案:

答案 0 :(得分:1)

使用awk可以选择字符串后面的字段。这是一个例子:

echo '2 of 10 19/4/2014 school name random text distance 800m more random text time 2:20:22 winner someonefast.' |
awk '{
    for(i=1; i<=NF; i++) {
        if ( i ~ /^[1345]$/ ) {
            extract = (extract ? extract FS $i : $i)
        }
        if ( $i ~ /distance|time/ ) {
            extract = (extract ? extract FS $(i+1): $(i+1))
        }
    }
    print extract
}'
2 10 19/4/2014 school 800m 2:20:22

我们在这里做的基本上是允许awk拆分为默认分隔符。我们创建一个for循环来迭代所有字段。 NF存储给定行的字段数。所以我们从1开始,一直到最后。

在我们的第一个条件块中,我们只检查字段编号。如果它是1或3或4或5,我们创建一个名为extract的变量,它连接由字段分隔符分隔的这些字段的值。

在我们的第二个条件块中,我们检查字段的值是距离还是时间。如果它是我们再次附加到我们的变量但是这次而不是当前值,我们做$(i+1)这基本上是下一个字段的值,或者你可以说一个字段的值跟在一个特定的字符串之后。

答案 1 :(得分:1)

当你有像这样的名字=值的情况时,最好创建一个数组,将名称映射到值,然后只打印你感兴趣的名称的值,例如:

$ awk '{for (i=1;i<=NF;i++) v[$i]=$(i+1); print $1, $3, $4, $5, v["distance"], v["time"]}' file
2 10 19/4/2014 school 800m 2:20:22

答案 2 :(得分:0)

基本:

awk '{
    for (i = 6; i <= NF; ++i) {
        if ($i == "distance") distance = $(i + 1)
        if ($i == "time") time = $(i + 1)
    }
    print $1, $3, $4, $5, distance, time
}' file

输出:

2 10 19/4/2014 school 800m 2:20:22

但是,在$5之后获取仍然属于学校名称的所有其他重要文本是不够的。你应该添加另一个条件。

更好的解决方案是除了标签之类的空格之外还有另一个分隔符,并使用\t作为FS