2013-10-26 97 views
5

我正在使用awk将字符串拆分为使用特定分隔符的数组。现在,我想对数组的每个元素执行一些操作。bash 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脚本这样的事情?

回答

15

你并不真的需要awk,bash可以自己完成一些字符串处理。

尝试:

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

如果你需要一个计数器,这是很微不足道的添加。

有关可直接在bash中执行操作的详细信息,请参阅How do I do string manipulations in bash?

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

这不包含bashisms,但适用于每个sh。

+0

请注意,这将覆盖'$ @'中的位置参数,所以在运行'set'命令之前,您需要保存它们。当然是 – chepner

+0

;通常情况下,我把复杂的任务放在有自己的$ @上下文的函数中(保存“$ @”太难看了,几乎不可能没有bashisms)。 – ensc

2

bash读取命令本身就是一个字符串分割成一个数组:

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,但集结在'声明':

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 
+0

这不适用于所有情况;留下'b'不加引号会使其受到路径名扩展以及分词的影响。 – chepner

11

这些答案都不使用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

+10

但是,如果问题是“如何在awk中执行此操作”,并且没有涉及awk的答案,则问题没有真正解答。结果是谷歌搜索返回一个无用的结果,任何人试图弄清楚如何在awk中完全做到这一点(这可能是有用的,因为他们已经在awk中做其他事情,只是想添加这一点)。 – 2015-11-20 17:49:07

+0

我的确在这个问题上找到了准确而具体的如何在awk中做到这一点。所以这个答案是我唯一的答案。 – Nick