Arrays 在bash中将字符串解析为包含空元素的数组

Arrays 在bash中将字符串解析为包含空元素的数组,arrays,bash,Arrays,Bash,伙计们。 目前,我正在尝试将lsblk输出解析到数组中,以便在bash中进行进一步分析。我唯一的问题是空列导致read-a将衰减值移动到假定为空的元素的错误位置。以下是一个例子: # lsblk -rno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN /usr/portage ext2 loop 4K disk 512B part 512B ext2 part 512B / ext4 part 512B /mnt/extended ext4 part 512B

伙计们。 目前,我正在尝试将
lsblk
输出解析到数组中,以便在bash中进行进一步分析。我唯一的问题是空列导致
read-a
将衰减值移动到假定为空的元素的错误位置。以下是一个例子:

# lsblk -rno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN 
/usr/portage ext2 loop 4K
  disk 512B
  part 512B
 ext2 part 512B
/ ext4 part 512B
/mnt/extended ext4 part 512B
第二行和第三行的MOUNTPOINT和FSTYPE以及第四行的MOUNTPOINT都是空的,但是“传统”是这样读的:

while read -r LINE; do
    IFS=' ' read -a ARRAY <<< $LINE
    echo "${ARRAY[0]};${ARRAY[1]};${ARRAY[2]};${ARRAY[3]}"
done < <(lsblk -rno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN)
所以,我想知道对于这种情况是否有一些“优雅”的解决方案,或者我是否应该像以前一样,借助trusty C中的
string.h


更清楚地说,我需要将这些值作为for循环中的数组元素进行分析,而不仅仅是打印这些值。回音只是作为不当行为的一个例子。

使用
awk
而不是
bash
。根据行中有多少字段,使用
NF
分配变量

awk -v 'OFS=;' 'NF == 4 { mountpoint = $1; fstype = $2; type = $3; gran = $4 }
                NF == 3 { mountpoint = ""; fstype = $1; type = $2; gran = $3 }
                NF == 2 { mountpoint = ""; fstype = ""; type = $1; gran = $2 }
                {print mountpoint, fstype, type, gran}' < <(lsblk -rno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN)
awk-v'OFS=;“NF==4{mountpoint=$1;fstype=$2;type=$3;gran=$4}
NF==3{mountpoint=”“;fstype=$1;type=$2;gran=$3}
NF==2{mountpoint=“”;fstype=“”;type=$1;gran=$2}

{print mountpoint,fstype,type,gran}<为什么不指定
-p
选项
lsblk
以key=“value”对的形式输出并读取输出

然后你可以这样说:

while read -ra a; do
    for ((i=0; i<${#a[@]}; i++)); do
        a[i]=${a[i]#*=}     # extract rvalue
        a[i]=${a[i]//\"/}   # remove surrounding quotes
    done
    (IFS=';'; echo "${a[*]}")
done < <(lsblk -Pno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN)
读取时-ra a;做

对于((i=0;这在
awk
中可能更容易,因为您可以更具体地检查行格式。
tr'';'<
while read -ra a; do
    for ((i=0; i<${#a[@]}; i++)); do
        a[i]=${a[i]#*=}     # extract rvalue
        a[i]=${a[i]//\"/}   # remove surrounding quotes
    done
    (IFS=';'; echo "${a[*]}")
done < <(lsblk -Pno MOUNTPOINT,FSTYPE,TYPE,DISC-GRAN)