c_arr
我有一个包含带有表别名的表列的数组。但数组中有一些元素实际上不是列,因此它们没有 format alias.column_name
。
我需要删除那些不包含.
.我怎样才能做到这一点?
该数组是使用以下语句创建的:
c_arr=($echo $(grep -io "\b$alias.\w[a-zA-Z_0-9]*" $output_file))
上面的行还有另一个问题。即使我正在搜索$alias.
(别名后面有一个点),该数组c_arr
也会获取其他不包含点的值。数组的示例值如下:
cab.SYSTEM_NAME
cab.row_id
cab.name
cabxa
cabxa
cab.x_sys_name
cab.status_Cd
cab.LAST_UPD
更新:
现在,手头的问题是如果数组中有点和非点元素,如何删除数组中c_arr
不包含字符的元素。.
内容c_arr
如下:
cab.SYSTEM_NAME
cab.row_id
cab.name
cabxa
cabxa
cab.x_sys_name
cab.status_Cd
cab.LAST_UPD
所需的输出是:
cab.SYSTEM_NAME
cab.row_id
cab.name
cab.x_sys_name
cab.status_Cd
cab.LAST_UPD
答案1
那么你可能想做这样的事情:
c_arr=$(echo $(grep -i "${alias}\." $output_file))
因为正如 Bill Jetzer 提到的,您必须转义正则表达式中的点。
如果您确定带点的所有内容都有效,您甚至可以这样做:
c_arr=$(echo $(grep -i \. $output_file))
答案2
具体回答“如何从 Bash 数组中删除不包含特定字符的元素”的问题。它在结构上与 Stéphane Chazelas 的答案非常相似。如果您有一个数组并且想要削减它,可以如下所示进行操作:
$ list=(cab.row_id cab.name cabxa cabxa cab.x_sys_name)
$ printf "%s\n" ${list[@]}
cab.row_id
cab.name
cabxa
cabxa
cab.x_sys_name
$ # vvvv THIS ANSWERS THE QUESTION vvvv
$ IFS=$'\n' readarray -t list < <(printf "%s\n" ${list[@]} | grep '\.')
$ # ^^^^ THIS ANSWERS THE QUESTION ^^^^
$ printf "%s\n" ${list[@]}
cab.row_id
cab.name
cab.x_sys_name
这假设没有元素包含 a,\n
因此它可以用作分隔符。
有点切线:您可以使用unset
从数组中删除特定元素,这将导致 Bash 在迭代元素时跳过该元素,但它会不是导致所有后续元素移动其数组索引值:
$ list=(idx0 idx1 idx2 idx3 idx4)
$ printf "%s\n" ${list[@]}
idx0
idx1
idx2
idx3
idx4
$ unset list[2]
$ printf "%s\n" ${list[@]}
idx0
idx1
idx3
idx4
$ for x in ${list[@]}; do echo $x; done
idx0
idx1
idx3
idx4
$ for i in $(seq 0 4); do echo "$i: ${list[$i]}"; done
0: idx0
1: idx1
2:
3: idx3
4: idx4
答案3
.
是匹配任何单个字符的正则表达式运算符。
在这里,您想要:
readarray -t c_arr < <(LC_ALL=C grep -iPo "\b\Q$alias\E\.\w+")
(假设$alias
不包含\E
并且您grep
支持-P
(它已经支持-o
这是一个 GNU 扩展,所以它很可能也会支持-P
))。