有时候,在过滤文本时,很多朋友可能希望根据给定条件或使用可匹配的特定模式来指示输入文件中的某些行或字符串行。这时候,使用Awk执行此操作非常简单,它是Awk的一大功能,你将会发现它很有用。
在接下来的awk命令系列内容中,小编将介绍如何根据用户可以定义的特定模式过滤文本或字符串,不多话一起来看看吧。
awk基于模式特定操作
首先看看下面的一个例子,假设你有一份想要购买的食品购物清单,名为food_prices.list,它有以下食品清单及其价格:
cat food_prices.list No Item_Name Quantity Price 1 Mangoes 10 $2.45 2 Apples 20 $1.50 3 Bananas 5 $0.90 4 Pineapples 10 $3.46 5 Oranges 10 $0.78 6 Tomatoes 5 $0.55 7 Onions 5 $0.45
然后,你想要在价格大于$2
的食品上标明标志(*)
,可以通过运行以下命令来完成:
awk '/ *$[2-9]\.[0-9][0-9] */ { print $1, $2, $3, $4, "*" ; } / *$[0-1]\.[0-9][0-9] */ { print ; }' food_prices.list
从上面的输出中,可以看到在食物为芒果和菠萝的行尾有一个(*)
标志。如果你查看它们的价格,它们的价格高于2美元。
实际上,在此示例中,使用了两种模式:
- 第一个:
/ *\$[2-9]\.[0-9][0-9] */
获取食品价格大于2美元的行; - 第二个:
/*\$[0-1]\.[0-9][0-9] */
寻找食品价格低于2美元的商品行。
大致工作原理是,文件中有四个字段,模式一遇到一行食品价格大于2美元时,它会打印所有四个字段,并在行末打印一个(*)
符号作为标志;模式二只是打印输入文件food_prices.list中食品价格低于2美元的其它行。
这样,你可以使用特定模式的操作来筛选出价格高于$2的食品项,不过输出存在一个问题,带有 (*) 标记的行没有像其它行那样进行格式化,这使得输出看起来不够清晰。
其实在Awk打印文件中的字段和列部分中看到了同样的问题,不过可以通过两种方式解决它。
1、使用printf命令,这是一个又长又无聊的方法,具体命令如下:
$ awk '/ *$[2-9]\.[0-9][0-9] */ { printf "%-10s %-10s %-10s %-10s\n", $1, $2, $3, $4 "*" ; } / *$[0-1]\.[0-9][0-9] */ { printf "%-10s %-10s %-10s %-10s\n", $1, $2, $3, $4; }' food_prices.list
2、使用$0字段,Awk使用变量0来存储整个输入行,这对于解决上述问题很方便,并且简单快捷,命令如下:
$ awk '/ *$[2-9]\.[0-9][0-9] */ { print $0 "*" ; } / *$[0-1]\.[0-9][0-9] */ { print ; }' food_prices.list
结论
以上就是Awk命令使用特定模式操作来过滤文本的简单方法,这些方法可以帮助标记文本文件或字符串中的行,在查找文件中的特点字符段时非常的有用。