对于刚刚在周末介绍它的人来说,我非常陌生。 我有一个问题,我希望有人可以帮助我。
如何选择特定字符串后面的字段?
如何扩展此代码以选择特定字符串后面的多个字段?
例如,对于我的文本文件中的任何给定行,我有类似
的内容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感兴趣。
非常感谢您的帮助。
安迪
答案 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
。