![awk:代码如何收集子字符串](https://linux22.com/image/106373/awk%EF%BC%9A%E4%BB%A3%E7%A0%81%E5%A6%82%E4%BD%95%E6%94%B6%E9%9B%86%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
如果这不是一个常见问题,请原谅我。我正在使用代码来获取第 n 个字段分隔符之前的子字符串:
echo '123-321-333-111-235'| awk -F"-" '
BEGIN {n=3}
{for(i=1;i<=n;++i)
k = k (k=="" ? "" : FS) $i;
print(k)
}'
这给出了
123-321-333
我不明白这条线是如何k = k (k=="" ? "" : FS) $i;
工作的。让我困惑的是三元运算符的k=k
and周围的部分。$i
我的问题只是想得到一个解释
答案1
echo '123-321-333-111-235' |
awk -F'-' -v n=3 '
{
for( i=1; i<=n; ++i )
k = k (k == "" ? "" : FS) $i
;
print k
}
'
循环for
运行 3 次:
i=1:
k is empty, $i -> $1 -> 123
k <= empty ( empty == empty ? empty : "-" ) 123
k <= empty empty 123
k <= "123"
i=2:
k is "123", $i -> $2 -> 321
k <= "123" ( 123 == empty ? empty : "-" ) 321
k <= "123" "-" "321"
k <= "123-321" due to the implicit concatenation property of awk strings
i=3:
k is "123-321", $i -> $3 -> 333
k <= "123-321" ( 123-321 == empty ? empty : "-" ) 333
k <= "123-321" "-" "333"
k <= "123-321-333"
This value of k is now sent to stdout.
STOP.
或者,您也可以执行以下操作:
n=3
echo '123-321-333-111-235' | sed -ne "s/-/\n/$n;P"
echo '123-321-333-111-235' | perl -F- -lane "\$, = '-'; print @F[0..$n-1]"
(
var='123-321-333-111-235'
set -f; IFS='-'; set -- $var
for((i=1;i<=$n;i++))
do
v=${v-}${v:+"$IFS"}$1
done
echo "$v"
# or, alternatively:
N=$#
while case $# in `expr $N - $n` ) break ;; esac; do
V=${V-}${V:+"$IFS"}$1
shift
done
echo "$V"
)
var='123-321-333-111-235'
FS='-'; # field separator provided here
fields=$(yes "[^$FS]*$FS" | head -n $n | tr -d '\n')
result=`expr "$var$FS" : "\($fields\)"`
echo "${result%?}"
答案2
如果您有k = k $i
,它会在当前处理的每个迭代字段的末尾添加k
(因此您将得到:123321333)。
如果您有k = k FS $i
,您将得到 -123-321-333。
三元if只是确保开头没有破折号,因为当awk处理$1时,k为空,因此三元if返回“”。