将字符串拆分为数组的Bash Awk

6
我正在使用awk将一个字符串按照特定的分隔符拆分成数组。现在,我想对数组中的每个元素执行一些操作。
我可以像这样提取单个元素:
#! /bin/bash

b=12:34:56
a=`echo $b | awk '{split($0,numbers,":"); print numbers[1]}'`
echo $a

我想要做类似这样的事情:
#! /bin/bash

b=12:34:56
`echo $b | awk '{split($0,numbers,":");}'`
for(i=0;i<length(numbers);i++)
{
   // perform some operation using numbers[i]
}

我该如何用Bash脚本实现类似的操作?

如下所述,您在这里真的不需要使用 awk,但如果您想要使用 awk 产生的结果“回到 shell”,则必须从 awk 中输出它;例如numbers=$(echo...|awk '{split(...);print numbers}'); for n in $numbers; do ... done(这比使用索引更简单,但您也可以使用 numbers=($(...)); for((i=0; i<${#numbers};++i)); do echo ${numbers[i]} ; done)。希望对您有所帮助。 - Max
5个回答

20

这些答案都没有使用awk(奇怪)。使用awk,您可以做到以下操作:

echo 12:34:56 | awk '{split($0,numbers,":")} END {for(n in numbers){ print numbers[n] }}'

print numbers[n]替换为您想要执行的任何操作。


1
他们不使用awk,因为没有理由启动一个外部程序来执行bash已经可以完成的任务。 - chepner
15
但是,如果问题是“如何在awk中完成此操作”,而没有任何答案涉及 awk,那么这个问题实际上并没有得到回答。结果是,对于任何试图弄清楚如何在awk中确切地完成此操作的人来说,谷歌搜索将返回无用的结果(这可能很有用,因为他们已经在awk中做了其他事情,只想添加这一个东西)。 - user153275
1
我确实来到这个问题,寻找如何在awk中准确和具体地执行它。因此,这个答案对我来说是唯一的答案。 - Nick

17

您实际上不需要awk来处理这个问题,bash可以自己完成一些字符串处理。

尝试使用:

b=12:34:56
for element in ${b//:/ } ; do
  echo $element
done

如果你需要一个计数器,添加它非常容易。

有关在Bash中直接执行的字符串操作,请参见如何在bash中进行字符串操作?了解更多信息。


6
b=12:34:56
IFS=:
set -- $b
for i; do echo $i; done

这段代码没有包含bashisms,但可以在任何sh环境下使用。


请注意,这将覆盖 $@ 中的位置参数,因此在运行 set 命令之前,您需要根据需要保存它们。 - chepner
当然,通常我会将复杂的任务放在具有自己$@上下文的函数中(保存"$@"太丑陋了,几乎不可能没有bashisms)。 - ensc

2

bashread 命令可以自行将字符串拆分为数组:

IFS=: read -a numbers <<< "$b"

为了确认它是否起作用:

echo "Hours: ${numbers[0]}"
echo "Minutes: ${numbers[1]}"
echo "Seconds: ${numbers[2]}"

for val in "${numbers[@]}"; do
   seconds=$(( seconds * 60 + $val ))
done

1

另一种不使用 awk,而是使用内置的“declare”的简洁方法:

b=12:34:56

# USE IFS for splitting (and elements can have spaces in them)
IFS=":"
declare -a elements=( $b )
#show contents
for (( i=0 ; i < ${#elements[@]}; i++ )); do
    echo "$i= ${elements[$i]}"
done

这并不适用于所有情况; 如果不将 b 用引号括起来,则它仍然会受到路径名扩展和单词分割的影响。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接