用于存储所有行的bash中的关联数组以X开头

时间:2014-09-21 14:32:20

标签: arrays linux bash unix awk

我有一个带有行的文件,我输入$ 1:

X B C D E
X G H I J
X L M N 
Y G  
Z B
Y L

在每一行以X开头,键是第二个元素,值是其余元素。

我正在按行创建文件行,为每个文件创建关联数组。

while read LINE
do
 INPUT=$(echo $LINE |awk '{print $1}')
 if [[ "$INPUT" = X ]]
 then
     key_name=$(echo $LINE | awk '{print $2}')
     declare -A dependencies 
     value_names=($(echo $LINE|awk '{$1=$2=""; print $0}'))
     dependencies[key_name]=value_names
     echo -e "\nvalues of $key_name are ${key_name[*]}\n"
     sleep 1
 fi
done < $1

所以我失去了每行阅读的价值。

但是我需要在关联阵列中存储带有X的所有行, 因为我需要稍后为后面的行搜索密钥,让我们说:一行以Y开头,它有G,所以在这里我需要从关联的数组中找到valuess 用钥匙G。

任何人都可以通过读取文件的折线来建议如何在一个关联数组中存储以X开头的所有行?还是更好的方法?

这里从给出的样本输入中,输出将分为3行:

H I J
C D E
M N

这里X,Y,X正在识别线条,如何处理下一个字符。如果X将其余部分存储在KEY-PAIR中,或者YZ从关联数组中提取值。

2 个答案:

答案 0 :(得分:2)

声明应该在循环之外。变量插值需要前面有一个美元符号。其余的只是重构。

declare -A dependencies
awk '$1=="X"{$1=""; print }' "$1" |
{ while read -r key value; 
  do
    dependencies["$key"]="$value"
    echo -e "\nvalues of $key_name are ${key_name[*]}\n"
    #sleep 1
  done
  :
  # do stuff with "${dependencies[@]}"
}

答案 1 :(得分:2)

将GNU awk用于gensub():

$ gawk '{ if (/^X/) a[$2] = gensub(/(\S+\s+){2}/,"",""); else print a[$2] }' file
H I J
C D E
M N

以上隐式循环遍历输入文件中的每一行,当它找到以X(/^X/)开头的行时,它会删除前2个非空格 - 空格对(gensub(/(\S+\s+){2}/,"","")并将结果存储在由原始第二个字段(a)索引的关联数组a[$2] = ...中,因此例如对于输入行X B C D E,它会保存a["B"] = "C D E"。如果该行没有以X(else)开头,那么它将打印当前行中第二个字段索引的数组,因此对于输入行Z B,它将执行print a["B"],因此输出C D E

使用旧版本的gawk(运行gawk --version并检查4.0之前的版本),您可能需要:

$ gawk --re-interval '{ if (/^X/) a[$2] = gensub(/([^[:space:]]+[[:space:]]+){2}/,"",""); else print a[$2] }' file

但是如果是这样的话,你会错过很多非常有用的功能,所以得到一个新的傻瓜!