使用Awk提取子字符串

时间:2013-04-16 15:07:21

标签: bash awk

给定格式为aaa0.bbb.ccc的主机名,我想在.之前提取第一个子字符串,即在这种情况下为aaa0。我使用以下awk脚本来执行此操作,

echo aaa0.bbb.ccc | awk '{if (match($0, /\./)) {print substr($0, 0, RSTART - 1)}}'

当在一台计算机A上运行的脚本生成aaa0时,在计算机B上运行只会生成aaa,最后不会生成0。这两台机器都运行Ubuntu/Linaro,但是A运行较新版本的awk(版本为3.1.8的gawk,而版本为B的版本为awk(版本为1.2的mawk)

我一般都在问,如何编写执行相同功能的兼容awk脚本......

5 个答案:

答案 0 :(得分:55)

您只想使用.选项将字段分隔符设置为-F并打印第一个字段:

$ echo aaa0.bbb.ccc | awk -F'.' '{print $1}'
aaa0

同样的事情,但使用cut:

$ echo aaa0.bbb.ccc | cut -d'.' -f1
aaa0

sed

$ echo aaa0.bbb.ccc | sed 's/[.].*//'
aaa0

grep

$ echo aaa0.bbb.ccc | grep -o '^[^.]*'
aaa0

答案 1 :(得分:5)

  

我一般都在问,如何编写兼容的awk脚本   执行相同的功能......

解决问题很容易。 (查看别人的回答)。

如果你想编写一个awk脚本,可以移植到任何awk实现和版本(gawk / nawk / mawk ...),那真的很难,即使用--posix(gawk)

例如:

  • 有些awk在字符串方面工作,有些用字节
  • 一些支持\x逃脱,一些不支持
  • FS口译员的工作方式不同
  • 关键字/保留字缩写限制
  • 一些运营商限制,例如**
  • 甚至同样的awk impl。 (例如gawk),版本4.0和3.x也有区别。
  • 某些功能的实现也不同。 (你的问题就是一个例子,见下文)

以上所有要点都是一般性的。回到你的问题,你的问题只与awk的基本功能有关。 awk '{print $x}'这样的一行将适用于所有问题。

为什么你的awk行在gawk和mawk上表现不同有两个原因:

  • 错误地使用了您的substr()函数。这是主要原因。无论您使用哪种awk,substr($0, 0, RSTART - 1) 0 1都应为substr()。 awk数组,字符串idx等是从1开始的。

  • gawk和mawk以不同方式实施{{1}}。

答案 2 :(得分:4)

或者只使用剪切:

echo aaa0.bbb.ccc | cut -d'.' -f1

答案 3 :(得分:2)

你不需要awk ......

echo aaa0.bbb.ccc | cut -d. -f1
cut -d. -f1 <<< aaa0.bbb.ccc

echo aaa0.bbb.ccc | { IFS=. read a _ ; echo $a ; }
{ IFS=. read a _ ; echo $a ; } <<< aaa0.bbb.ccc 

x=aaa0.bbb.ccc; echo ${x/.*/}

更重要的选项:

sed:
echo aaa0.bbb.ccc | sed 's/\..*//'
sed 's/\..*//' <<< aaa0.bbb.ccc 
awk:
echo aaa0.bbb.ccc | awk -F. '{print $1}'
awk -F. '{print $1}' <<< aaa0.bbb.ccc 

答案 4 :(得分:2)

根本不需要任何外部命令,只需在bash中使用参数扩展:

hostname=aaa0.bbb.ccc
echo ${hostname%%.*}