我想用 awk 对数据进行子集化。假设我有一个名为 test 的文件:
IP MAC Bandwidth etc etc
192.1.1.1 ff:ff:ff:ff 5.421M
192.1.2.3 ff:ff:ff:f3 5.120M
192.1.2.5 ff:ff:ff:f1 5.100M
stuff I don't want to be selected
我只想选择 bandwith 值(如果我可以删除 M 和结尾会更好,也许使用 sed,我不知道如何,但这不是主要问题。)
我目前正在做的最好的子集是:
awk '{print $3}' test
输出是这样的:
Bandwidth
5.421M
5.120M
5.100M
dont
但我希望它是:
5.421
5.120
5.100
如果“M”在那里,那不是问题,但这就是想法。我一直在收集有关 awk 的信息并尝试一些东西,但还没有找到解决方案。
答案1
确切的答案需要您进一步具体说明您的问题。然而,awk 语句的一般语法是:
PATTERN { ACTION }
ACTION 只会对匹配 PATTERN 的行执行。因此,我们可以使用PATTERN
按行进行子集化,并使用 ACTION 块按列进行子集化。例如,根据您的输入,我可能会使用以下内容:
> awk '/^[0-9]/ {print $3 }' INPUTFILE
5.421M
5.120M
5.100M
这里PATTERN
是一个正则表达式,它匹配第一个字符是 0 到 9 之间的整数的任何行。要删除,M
您可以将其通过管道传输到另一个命令,例如tr
或使用gsub
cuonglm 的答案中的命令
awk '/^[0-9]/ { gsub(/M/, "", $3); print $3 }' INPUT_FILE
答案2
您可以在打印之前删除所有非数字或点的内容:
$ awk '{gsub(/[^[:digit:].]/,"",$3);print $3}' file
5.421
5.120
5.100
答案3
如果您不打算对文本进行某些操作,那么sed
使用似乎更合理
sed -En 's/.* (\S+)M$/\1/p'
-E
让我们避免使用反斜杠(\(, \+,
等)的元字符
-n
抑制输出,除非按以下顺序排列p
s/
代替
.*
空格行的第一部分(最后一个空格因为贪婪)
()
“反转链接” - 您可以通过以下方式调用括号内的模式\number
\S
每个非空间符号(除了 之外的所有符号:blank:
)
+
一个或多个先前的符号
M$
“M”位于行尾
/p
打印进行替换的行
含义是“用括号内的模式替换整行并打印仅进行此类替换的行”
答案4
您也可以使用 awk 中的 match 函数。
awk '{match($3, /[0-9]+.[0-9]+/,arr)}{ print arr[0]}' file