在 AIX 中使用单个 AWK 从字段中提取子字符串

问题描述 投票:0回答:6

我有一个文件,

file
,内容如下:

stringa    8.0.1.2     stringx
stringb    12.01.0.0    stringx

我必须从字段 2 中获取一个子字符串(前两个带点的值)。 我目前正在做

cat file | awk '{print $2}' | awk -F. '{print $1"."$2}'
并得到预期的输出:

8.0
12.01

如何使用单个 AWK 来完成此操作?

我尝试过使用 match(),但我没有看到向后引用的选项。

awk grep ksh aix
6个回答
4
投票

你可以做这样的事情。

awk '{ split($2,str,"."); print 

输出:

str[1]"."str[2] }' file
8.0
12.01

另外,请记住,不需要您的

cat
。只需将文件直接交给
awk
即可。


4
投票

使用 GNU

grep
请尝试执行以下命令一次。

grep -oP '^\S+\s+\K[[:digit:]]+\.[[:digit:]]+' Input_file

说明:此处使用GNU

grep
。使用其
-oP
选项打印匹配的部分,并在此处使用
-P
选项启用 PCRE。在主程序中,从起始非空格字符开始匹配,后跟 1 个或多个空格,然后使用
\K
选项忘记该匹配。然后匹配 1 个或多个数字出现,后跟一个点;接下来是数字。如果找到匹配项,则会打印匹配的值。


2
投票

我会使用GNU

AWK
split
函数如下,让file.txt内容为

stringa    8.0.1.2     stringx
stringb    12.01.0.0    stringx

然后

awk '{split($2,arr,".");print arr[1]"."arr[2]}' file.txt

输出

8.0
12.01

解释:在

.
第二个字段处拆分并将元素放入数组
arr

(在 gawk 4.2.1 中测试)


2
投票

您可以匹配数字。第二列中的数字,如果有匹配则打印:

awk 'match($2, /^[[:digit:]]+\.[[:digit:]]+/) {
    print substr($2, RSTART, RLENGTH)
}
' file

输出

8.0
12.01

2
投票

还有 GNU

awk
gensub()

awk '{print gensub(/([[:digit:]]+[.][[:digit:]]+)(.*)/,"\\1","g",$2)}' file
8.0
12.01
  • gensub()
    提供了在替换文本中指定正则表达式组件的功能,使用正则表达式中的括号来标记组件,然后在替换文本中指定
    \\n
    ,其中
    n
    是从 1 到 9 的数字。

0
投票

您也许根本不应该使用 awk(或任何其他外部程序),而应该依赖 shell 的字段分割功能和一些变量扩展。例如:

 # printf "%s\n%s\n" "stringa    8.0.1.2     stringx" \
                     "stringb    12.01.0.0    stringx" |\
   while read first second third junk ; do
        printf "=%s= =%s= =%s=\n" "$first" "$second" "$third"
   done
   =stringa= =8.0.1.2= =stringx=
   =stringb= =12.01.0.0= =stringx=

正如您所看到的,该值已经被捕获在变量“$second”中,您只需要进一步隔离您想要查看的部分 - 第一个和第二个部分用点分隔。您可以通过参数扩展来做到这一点:

 # variable="8.0.1.2"
 # echo ${variable%.*.*}
   8.0

或者像这样:

 # variable="12.01.0.0"
 # echo ${variable%${variable#*.*.}}
   12.01

或者您可以使用进一步的读取语句来分离各个部分,然后将它们重新组合在一起:

 # variable="12.01.0.0"
 # echo ${variable} | IFS=. read parta partb junk
 # echo ${parta}.${partb}
   12.01

所以,把所有的放在一起:

 # printf "%s\n%s\n" "stringa    8.0.1.2     stringx" \
                     "stringb    12.01.0.0    stringx" |\
   while read first second third junk ; do
        printf "%s\n" "$second" | IFS=. read parta partb junk
        printf "%s.%s\n" "$parta" "$partb"
   done
   8.0
   12.01
© www.soinside.com 2019 - 2024. All rights reserved.