从 grep 输出创建关联数组
Create associative array from grep output
我有一个 grep 输出,我正在尝试从我得到的输出中创建一个关联数组。
这是我的 grep 输出:
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
我想使用该输出来定义关联数组,如下所示:
array[123456789101]=devid1234
array[11213141516]=devid5678
这可能吗?我是制作数组的新手。我希望有人能帮助我解决我的问题。
要么将您的 grep
输出通过 while
循环通过管道传输到辅助脚本,其中包含一个简单的 "0/1"
切换以读取两行,每行的最后一个字段填充您的数组,例如
#!/bin/bash
declare -A array
declare -i n=0
arridx=
while read -r label value; do # read 2 fields
if [ "$n" -eq 0 ]
then
arridx="${value:1}" # strip 1st and lst 2 chars
arridx="${arridx:0:(-2)}" # save in arridx (array index)
((n++)) # increment toggle
else
arrval="${value:1}" # strip 1st and lst 2 chars
arrval="${arrval:0:(-2)}" # save in arrval (array value)
array[$arridx]="$arrval" # assign to associative array
n=0 # zero toggle
fi
done
for i in ${!array[@]}; do # output array
echo "array[$i] ${array[$i]}"
done
或者您可以在脚本中使用包含 grep
命令的 进程替换 来做同样的事情,例如
done < <( your grep command )
您还可以在 else
子句下添加检查 if [[ $label =~ DeviceId ]]
以验证您是否在正确的行上并捕获 grep
输出内容中的任何变化。
示例输入
$ cat dat/grepout.txt
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
例子Use/Output
$ cat dat/grepout.txt | bash parsegrep2array.sh
array[123456789101] devid1234
array[111213141516] devid5678
解析这些值很容易,一旦你有了它们,你当然可以使用这些值来构建一个数组。最棘手的部分来自于您需要合并来自不同行的输入这一事实。这是一种方法;请注意,此脚本是故意冗长的,以显示正在发生的事情;一旦你看到发生了什么,你就可以消除大部分输出:
so.input
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
so.sh
#!/bin/bash
declare -a hardwareInfo
while [[ 1 ]]; do
# read in two lines of input
# if either line is the last one, we don't have enough input to proceed
read lineA < "${1:-/dev/stdin}"
# if EOF or empty line, exit
if [[ "$lineA" == "" ]]; then break; fi
read lineB < "${1:-/dev/stdin}"
# if EOF or empty line, exit
if [[ "$lineB" == "" ]]; then break; fi
echo "$lineA"
echo "$lineB"
hwsn=$lineA
hwsn=${hwsn//HardwareSerialNumber/}
hwsn=${hwsn//\"/}
hwsn=${hwsn//:/}
hwsn=${hwsn//,/}
echo $hwsn
# some checking could be done here to test that the value is numeric
devid=$lineB
devid=${devid//DeviceId/}
devid=${devid//\"/}
devid=${devid//:/}
devid=${devid//,/}
echo $devid
# some checking could be done here to make sure the value is valid
# populate the array
hardwareInfo[$hwsn]=$devid
done
# spacer, for readability of the output
echo
# display the array; in your script, you would do something different and useful
for key in "${!hardwareInfo[@]}"; do echo $key --- ${hardwareInfo[$key]}; done
猫so.input | ./so.sh
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
123456789101
devid1234
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
111213141516
devid5678
111213141516 --- devid5678
123456789101 --- devid1234
我创建输入文件 so.input
只是为了方便。您可能会将 grep
输出通过管道传输到 bash 脚本中,如下所示:
grep-command | ./so.sh
编辑 #1:从 grep
输入的字符串中解析键和值有很多选择; @David C. Rankin 的回答显示了另一种方式。最好的方法取决于您对 grep
输出的内容和结构的依赖。
阅读彼此相关的两行单独的内容也有多种选择; David的"toggle"方法也不错,常用;在使用 "read two lines and stop if either is blank".
之前,我自己考虑过
编辑 #2:我在 David 的回答和网络上的示例中看到 declare -A
;我使用 declare -a
因为那是我的 bash
版本想要的(我使用的是 Mac)。因此,请注意 可能 存在差异。
我有一个 grep 输出,我正在尝试从我得到的输出中创建一个关联数组。
这是我的 grep 输出:
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
我想使用该输出来定义关联数组,如下所示:
array[123456789101]=devid1234
array[11213141516]=devid5678
这可能吗?我是制作数组的新手。我希望有人能帮助我解决我的问题。
要么将您的 grep
输出通过 while
循环通过管道传输到辅助脚本,其中包含一个简单的 "0/1"
切换以读取两行,每行的最后一个字段填充您的数组,例如
#!/bin/bash
declare -A array
declare -i n=0
arridx=
while read -r label value; do # read 2 fields
if [ "$n" -eq 0 ]
then
arridx="${value:1}" # strip 1st and lst 2 chars
arridx="${arridx:0:(-2)}" # save in arridx (array index)
((n++)) # increment toggle
else
arrval="${value:1}" # strip 1st and lst 2 chars
arrval="${arrval:0:(-2)}" # save in arrval (array value)
array[$arridx]="$arrval" # assign to associative array
n=0 # zero toggle
fi
done
for i in ${!array[@]}; do # output array
echo "array[$i] ${array[$i]}"
done
或者您可以在脚本中使用包含 grep
命令的 进程替换 来做同样的事情,例如
done < <( your grep command )
您还可以在 else
子句下添加检查 if [[ $label =~ DeviceId ]]
以验证您是否在正确的行上并捕获 grep
输出内容中的任何变化。
示例输入
$ cat dat/grepout.txt
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
例子Use/Output
$ cat dat/grepout.txt | bash parsegrep2array.sh
array[123456789101] devid1234
array[111213141516] devid5678
解析这些值很容易,一旦你有了它们,你当然可以使用这些值来构建一个数组。最棘手的部分来自于您需要合并来自不同行的输入这一事实。这是一种方法;请注意,此脚本是故意冗长的,以显示正在发生的事情;一旦你看到发生了什么,你就可以消除大部分输出:
so.input
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
so.sh
#!/bin/bash
declare -a hardwareInfo
while [[ 1 ]]; do
# read in two lines of input
# if either line is the last one, we don't have enough input to proceed
read lineA < "${1:-/dev/stdin}"
# if EOF or empty line, exit
if [[ "$lineA" == "" ]]; then break; fi
read lineB < "${1:-/dev/stdin}"
# if EOF or empty line, exit
if [[ "$lineB" == "" ]]; then break; fi
echo "$lineA"
echo "$lineB"
hwsn=$lineA
hwsn=${hwsn//HardwareSerialNumber/}
hwsn=${hwsn//\"/}
hwsn=${hwsn//:/}
hwsn=${hwsn//,/}
echo $hwsn
# some checking could be done here to test that the value is numeric
devid=$lineB
devid=${devid//DeviceId/}
devid=${devid//\"/}
devid=${devid//:/}
devid=${devid//,/}
echo $devid
# some checking could be done here to make sure the value is valid
# populate the array
hardwareInfo[$hwsn]=$devid
done
# spacer, for readability of the output
echo
# display the array; in your script, you would do something different and useful
for key in "${!hardwareInfo[@]}"; do echo $key --- ${hardwareInfo[$key]}; done
猫so.input | ./so.sh
"HardwareSerialNumber": "123456789101",
"DeviceId": "devid1234",
123456789101
devid1234
"HardwareSerialNumber": "111213141516",
"DeviceId": "devid5678",
111213141516
devid5678
111213141516 --- devid5678
123456789101 --- devid1234
我创建输入文件 so.input
只是为了方便。您可能会将 grep
输出通过管道传输到 bash 脚本中,如下所示:
grep-command | ./so.sh
编辑 #1:从 grep
输入的字符串中解析键和值有很多选择; @David C. Rankin 的回答显示了另一种方式。最好的方法取决于您对 grep
输出的内容和结构的依赖。
阅读彼此相关的两行单独的内容也有多种选择; David的"toggle"方法也不错,常用;在使用 "read two lines and stop if either is blank".
之前,我自己考虑过编辑 #2:我在 David 的回答和网络上的示例中看到 declare -A
;我使用 declare -a
因为那是我的 bash
版本想要的(我使用的是 Mac)。因此,请注意 可能 存在差异。