【发布时间】:2015-02-28 16:05:36
【问题描述】:
我知道在 BEGIN 中初始化 FS 是正确的做法,但是如果我需要为不同的行(包含特定模式的行)使用不同的字段分隔符怎么办?例如:我的 awk 脚本是
{if($0 ~ /.*youtube.*/){FS="=";print $2}}
这段代码没有处理第一行。如何解决这个问题?
【问题讨论】:
我知道在 BEGIN 中初始化 FS 是正确的做法,但是如果我需要为不同的行(包含特定模式的行)使用不同的字段分隔符怎么办?例如:我的 awk 脚本是
{if($0 ~ /.*youtube.*/){FS="=";print $2}}
这段代码没有处理第一行。如何解决这个问题?
【问题讨论】:
您可以使用split。 Eks 从第三字段green获取中间日期
echo "on,cat ,blue|green|red,more" | awk -F, '{split($3,a,"|");print a[2]}'
green
而你BEGIN 块不仅是你可以设置字段分隔符的地方:
echo "on,two,three" | awk -F, '{print $2}'
echo "on,two,three" | awk '{print $2}' FS=,
echo "on,two,three" | awk 'BEGIN{FS=","} {print $2}'
echo "on,two,three" | awk -v FS=, '{print $2}'
所有这些都将打印two
但它们在何时可以使用时可能会产生一些不同的影响。
awk -F, 'BEGIN{print FS}'
,
这不起作用并且没有输出。
awk 'BEGIN{print FS}' FS=,
回到你的问题:
这个:
awk '{if($0 ~ /.*youtube.*/){FS="=";print $2}}' file
应该是:
awk '{if($0 ~ /.*youtube.*/){split($0,a,"=");print a[2]}}' file
你不需要在正则表达式之前和之后测试任何字符,所以:
awk '{if($0 ~ /youtube/){split($0,a,"=");print a[2]}}' file
这可以更加简化:
awk '/youtube/ {split($0,a,"=");print a[2]}' file
如果数据是这样的:
cat file
youtube=thisisyoutube1 //starts here
youtube=thisisyoutube2
youtube=thisisyoutube3
youtube=thisisyoutube4
yautube=thisisnottobeprinted
然后这样做:
awk -F= '/youtube/ {split($2,a," ");print a[1]}' file
thisisyoutube1
thisisyoutube2
thisisyoutube3
thisisyoutube4
【讨论】:
{}。发布输入数据以及从中得到什么。
split($0,a,/=/) 而不是split($0,a,"=")) 所以 awk 不必将该 arg 从字符串转换为正则表达式。该论点的某些内容很重要,因此养成避免意外的好习惯。