awk
我尝试在循环内使用命令,但没有成功for
。
我有一个变量,其中包含一系列字符串,我想用它们来剪切以awk
获取数据。
我知道该怎么做,但我真正想要的是连续剪切数据。
所以我有这个变量:
var="data1,data2,data3"
我现在就在这里:
for ((i=1; i<=3; i++))
do
echo $(awk -F, '{print $1}' <<< $var)
done
我尝试$1
用循环替换$i
,但没有成功。
答案1
您可以通过在 awk 脚本中使用双引号将 shell 变量注入其中来完成您想要做的事情。您仍然想$
在其中保留一个文字,可以通过使用反斜杠转义它来实现:
echo $(awk -F, "{print \$$i}" <<<$var)
这将在每次迭代中扩展,$i
和,因此 awk 将看到,和 ,这将使其扩展每个字段。1
2
3
$1
$2
$3
另一种可能性是使用以下标志将 shell 变量作为 awk 变量注入-v
:
echo $(awk -F, -v i="$i" '{print $i}' <<<$var)
分配 awk 变量我到同名的 shell 变量的内容。 awk 中的变量不使用 a $
,它用于字段,因此$i
足以引用我-第一个字段如果我是 awk 中的变量。
为 awk 变量赋值-v
通常是一种更安全的方法,特别是当它可以包含任意字符序列时,在这种情况下,内容将作为 awk 代码执行违背您的意图的风险较小。但由于在您的情况下变量保存单个整数,因此不必担心。
for
另一种选择是在 awk 本身中使用循环。有关如何执行此操作的更多详细信息,请参阅 awk 文档(或搜索此站点)。
答案2
在这种情况下使用似乎有点过多,那么使用 a和 while 循环awk
怎么样:tr
tr , '\n' <<<"$var" | while read; do
echo $REPLY
done
输出:
data1
data2
data3
答案3
#!/bin/sh
var='data1,data2,data3'
unset data
while [ "$var" != "$data" ]; do
data=${var%%,*} # delete first comma and the bit after it
var=${var#*,} # delete bit up to first comma (and the comma)
printf 'data = "%s"\n' "$data"
done
在这里,我们使用变量替换从变量的值中获取每个连续的逗号分隔数据字段var
。data
循环中的第一个赋值将删除$var
第一个逗号之后的所有内容。然后修改该var
变量,以便删除第一个逗号之前的第一位。
这一直持续到"$var" = "$data"
这意味着不能对字符串执行任何操作。
这种方法允许我们处理包含嵌入换行符的逗号分隔数据字符串:
var='line1
line2,data2,last bit
goes here'
使用上述值var
,上面的脚本将输出
data = "line1
line2"
data = "data2"
data = "last bit
goes here"
不关心嵌入的换行符;你很少必须循环调用awk
.
请注意,awk
非常乐意将字符串读取为一组逗号分隔的字段,并且它能够循环这些字段:
printf '%s\n' "$var" |
awk -F ',' '{ for (i=1; i<=NF; i++) print $i }'
使用var='data1,data2,data3'
,这将打印
data1
data2
data3
另一种 shell 解决方案利用IFS
变量将$var
值拆分为位,同时还使用set -f
禁用文件名扩展:
set -f
oldIFS=$IFS; IFS=','
set -- $var
IFS=$oldIFS; unset oldIFS
set +f
for data do
printf 'data = "%s"\n' "$data"
done