如何重建没有空元素的数组?

时间:2019-08-29 19:41:13

标签: arrays bash shell grep

我正在尝试从具有空元素的字符串数组中创建一个没有空元素的新字符串数组。

代码

#!/bin/bash
inlist=(a b c d)  # inlist to be processed
outlist=(a b)     # outlist to be deleted from inlist

for i in "${outlist[@]}"; do
    inlist=( "${inlist[@]/$i}" )  # use outlist to remove elements from inlist
done

for i in "${!inlist[@]}"; do  # create new inlist without null elements
#   if []; then
    templist+=( "${inlist[i]}" )
#   fi
done

inlist=("${templist[@]}")
unset templist

for i in "${!inlist[@]}"; do
    echo "$i" "${inlist[i]}"
done

意外结果

0
1
2 c
3 d

预期结果

0 c
1 d

一旦数组处理正常,我想扩展脚本以处理文件列表,例如

扩展

mapfile -t inlist < inlist.txt
mapfile -t outlist < outlist.txt

inlist.txt
file1.txt
file2.txt
file3.txt
file4.txt

outlist1.txt
file1.txt
file2.txt

我正在学习bash,并研究有关运算符,扩展和替换的一些基本概念。

赞赏任何解释或冗长的代码建议。

问题似乎是for循环在将空元素添加到临时数组时没有忽略空元素。

预先感谢

2 个答案:

答案 0 :(得分:2)

navLink: { '&:hover': { borderBottom: '2px solid mediumvioletred', background: '#8DB8DD', cursor: 'pointer', // '& div': { // '&:hover': { // borderBottom: 'none', // } // }, // '&> div &:hover': { // borderBottom: 'none', // } }, '&:hover > div:hover': { borderBottom: 'none' } }, 仍然具有与templist相同的所有空字符串。您想要类似的东西

inlist

现在for i in "${inlist[@]}"; do if [ -n "$i" ]; then templist+=( "$i" ) fi done 将根据需要重置inlist=("${templist[@]}")

您也可以使用

inlist

这会使for i in "${!inlist[@]}"; do if [ -z "${inlist[i]}" ]; then unset "inlist[i]" fi done 处于略有不同的状态:

inlist

但是$ declare -p inlist declare -a inlist=([2]="c" [3]="d") 在构建新数组时将忽略实际索引。


提供两个输入文件,

inlist=("${inlist[@]}")

答案 1 :(得分:1)

使用joincomm提取不在一个列表中但在另一个列表中的元素。

在我printf下,将数组作为零分隔的流,sort,然后在它们上依次comm,然后readarray进入inlist

inlist=(a b c d)
outlist=(a b)
IFS= readarray -d '' inlist < <(comm -z -23 <(printf "%s\0" "${inlist[@]}" | sort -z) <(printf "%s\0" "${outlist[@]}" | sort -z))
declare -p inlist

将输出:

declare -a inlist=([0]="c" [1]="d")

注意:

  • 这可能会很快
  • -z for comm是gnu扩展名
  • 由于元素在comm之前排序,因此您将失去元素顺序。

在bash 4.4之前的版本中,没有-d选项的readarray选项,您可以逐行读取数组并将其追加到数组中:

inlist=(a b c d)
outlist=(a b)
while IFS= read -d '' -r a; do
    tmplist+=("$a")
done < <(comm -z -23 <(printf "%s\0" "${inlist[@]}" | sort -z) <(printf "%s\0" "${outlist[@]}" | sort -z))
declare -p tmplist