使用 awk 对数据进行子集化

使用 awk 对数据进行子集化

我想用 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或使用gsubcuonglm 的答案中的命令

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

相关内容