在 AIX 中使用单个 awk 从字段中提取子字符串
Extract substring from a field with single awk in AIX
我有一个文件 file
,其内容如下:
stringa 8.0.1.2 stringx
stringb 12.01.0.0 stringx
我必须从字段 2 中获取一个子字符串(前两个带点的值)。
我目前正在做 cat file | awk '{print }' | awk -F. '{print "."}'
并获得预期的输出:
8.0
12.01
查询是如何用单个 awk 做到这一点?
我试过 match() 但没有看到反向引用的选项。
任何帮助将不胜感激。
你可以这样做。
$ awk '{ split(,str,"."); print str[1]"."str[2] }' file
8.0
12.01
此外,请记住您的 cat
不是必需的。直接把文件给awk
.
我会使用 GNU AWK
的 split
函数如下,令 file.txt 内容为
stringa 8.0.1.2 stringx
stringb 12.01.0.0 stringx
然后
awk '{split(,arr,".");print arr[1]"."arr[2]}' file.txt
输出
8.0
12.01
解释:在 .
第二个字段拆分并将元素放入数组 arr
.
(在 gawk 4.2.1 中测试)
您可以匹配 digits 。来自第二列的 digits 并打印是否匹配:
awk 'match(, /^[[:digit:]]+\.[[:digit:]]+/) {
print substr(, RSTART, RLENGTH)
}
' file
输出
8.0
12.01
使用 GNU grep
请尝试执行以下命令一次。
grep -oP '^\S+\s+\K[[:digit:]]+\.[[:digit:]]+' Input_file
说明: 这里使用 GNU grep
。使用其 -oP
选项打印匹配的部分并在此处使用 -P
选项启用 PCRE。在主程序中,从非 space 字符开始匹配,后跟 1 个或多个 spaces,然后使用 \K
选项忘记该匹配。然后匹配 1 个或多个数字出现后跟一个点;随后是数字。如果找到匹配项,则打印匹配值。
还有 GNU awk
和 gensub()
:
awk '{print gensub(/([[:digit:]]+[.][[:digit:]]+)(.*)/,"\1","g",)}' file
8.0
12.01
gensub()
提供了在替换文本中指定正则表达式组件的功能,使用正则表达式中的括号来标记组件,然后在替换文本中指定 \n
,其中 n
是从 1 到 9 的数字。
您也许根本不应该使用 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
我有一个文件 file
,其内容如下:
stringa 8.0.1.2 stringx
stringb 12.01.0.0 stringx
我必须从字段 2 中获取一个子字符串(前两个带点的值)。
我目前正在做 cat file | awk '{print }' | awk -F. '{print "."}'
并获得预期的输出:
8.0
12.01
查询是如何用单个 awk 做到这一点?
我试过 match() 但没有看到反向引用的选项。
任何帮助将不胜感激。
你可以这样做。
$ awk '{ split(,str,"."); print str[1]"."str[2] }' file
8.0
12.01
此外,请记住您的 cat
不是必需的。直接把文件给awk
.
我会使用 GNU AWK
的 split
函数如下,令 file.txt 内容为
stringa 8.0.1.2 stringx
stringb 12.01.0.0 stringx
然后
awk '{split(,arr,".");print arr[1]"."arr[2]}' file.txt
输出
8.0
12.01
解释:在 .
第二个字段拆分并将元素放入数组 arr
.
(在 gawk 4.2.1 中测试)
您可以匹配 digits 。来自第二列的 digits 并打印是否匹配:
awk 'match(, /^[[:digit:]]+\.[[:digit:]]+/) {
print substr(, RSTART, RLENGTH)
}
' file
输出
8.0
12.01
使用 GNU grep
请尝试执行以下命令一次。
grep -oP '^\S+\s+\K[[:digit:]]+\.[[:digit:]]+' Input_file
说明: 这里使用 GNU grep
。使用其 -oP
选项打印匹配的部分并在此处使用 -P
选项启用 PCRE。在主程序中,从非 space 字符开始匹配,后跟 1 个或多个 spaces,然后使用 \K
选项忘记该匹配。然后匹配 1 个或多个数字出现后跟一个点;随后是数字。如果找到匹配项,则打印匹配值。
还有 GNU awk
和 gensub()
:
awk '{print gensub(/([[:digit:]]+[.][[:digit:]]+)(.*)/,"\1","g",)}' file
8.0
12.01
gensub()
提供了在替换文本中指定正则表达式组件的功能,使用正则表达式中的括号来标记组件,然后在替换文本中指定\n
,其中n
是从 1 到 9 的数字。
您也许根本不应该使用 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