从数组中删除不包含特定字符的元素

从数组中删除不包含特定字符的元素

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))。

相关内容