You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将文件单行含空格的元素读取到Bash数组?

Bash从单行文件读取带空格的数组元素解决方案

问题描述

测试代码尝试从单行文件读取带空格的元素到数组,但所有尝试的方法都无法像直接定义数组ARRAY_1那样,将含空格的内容作为单个元素,而是被错误分割成多个元素。

测试代码

#!/bin/bash

# Declare array with 4 elements
#
ARRAY_1=( 'Debian Linux' 'Redhat Linux' Ubuntu Linux )

# Contents of ARRAY_1
#
echo ARRAY_1: ${ARRAY_1[@]}

# Get number of elements in the array
#
NUM_ELEMENTS=${#ARRAY_1[@]}

# echo each element in array
#
for (( i=0;i<$NUM_ELEMENTS;i++ )); do
    echo ${ARRAY_1[${i}]}
done

echo
echo Now try with reading from a file.
echo The goal is to behave like ARRAY_1
echo Note: Its important that all the elements appear
echo on one line in the file.
echo

tmpFile=/tmp/TEST_ELEMENTS.$$
cat << EOF > $tmpFile
'Debian Linux' 'Redhat Linux' Ubuntu Linux
EOF

# How to get this to behave like ARRAY_1 assignment above?
#
# ARRAY_2=( `eval "cat $tmpFile"` )        # Nope.
# ARRAY_2=( $(cat $tmpFile) )              # Also Nope
# ARRAY_2=( $(xargs < $tmpFile) )          # Also Nope
declare -a ARRAY_2=( $(xargs < $tmpFile) )   # Also Nope

echo ARRAY_2: ${ARRAY_2[@]}
NUM_ELEMENTS=${#ARRAY_2[@]}

for (( i=0;i<$NUM_ELEMENTS;i++ )); do
    echo ${ARRAY_2[${i}]}
done

/bin/rm $tmpFile

错误输出

ARRAY_1: Debian Linux Redhat Linux Ubuntu Linux
Debian Linux
Redhat Linux
Ubuntu
Linux

Now try with reading from a file.
The goal is to behave like ARRAY_1
Note: Its important that all the elements appear
on one line in the file.

ARRAY_2: Debian Linux Redhat Linux Ubuntu Linux
Debian
Linux
Redhat
Linux
Ubuntu
Linux

解决方案

核心问题是直接使用$(cat $tmpFile)这类方式时,Bash会先进行分词,把单引号当成普通字符处理,导致带空格的元素被拆分。正确的做法是利用eval重新解析文件内容的引号结构,让Bash识别带空格的元素为单个数组项。

修改后的数组赋值代码如下:

# 正确的赋值方式
eval "ARRAY_2=( $(cat "$tmpFile") )"

完整修正后的代码

#!/bin/bash

# Declare array with 4 elements
#
ARRAY_1=( 'Debian Linux' 'Redhat Linux' Ubuntu Linux )

# Contents of ARRAY_1
#
echo ARRAY_1: ${ARRAY_1[@]}

# Get number of elements in the array
#
NUM_ELEMENTS=${#ARRAY_1[@]}

# echo each element in array
#
for (( i=0;i<$NUM_ELEMENTS;i++ )); do
    echo ${ARRAY_1[${i}]}
done

echo
echo Now try with reading from a file.
echo The goal is to behave like ARRAY_1
echo Note: Its important that all the elements appear
echo on one line in the file.
echo

tmpFile=/tmp/TEST_ELEMENTS.$$
cat << EOF > $tmpFile
'Debian Linux' 'Redhat Linux' Ubuntu Linux
EOF

# 正确的赋值方式
eval "ARRAY_2=( $(cat "$tmpFile") )"

echo ARRAY_2: ${ARRAY_2[@]}
NUM_ELEMENTS=${#ARRAY_2[@]}

for (( i=0;i<$NUM_ELEMENTS;i++ )); do
    echo ${ARRAY_2[${i}]}
done

/bin/rm $tmpFile

正确输出

ARRAY_1: Debian Linux Redhat Linux Ubuntu Linux
Debian Linux
Redhat Linux
Ubuntu
Linux

Now try with reading from a file.
The goal is to behave like ARRAY_1
Note: Its important that all the elements appear
on one line in the file.

ARRAY_2: Debian Linux Redhat Linux Ubuntu Linux
Debian Linux
Redhat Linux
Ubuntu
Linux

原理说明

  • $(cat "$tmpFile")读取文件内容后,会保留原始的引号结构;
  • eval会让Bash重新解析整个赋值语句,识别单引号作为字符串边界,从而将'Debian Linux'这类带空格的内容视为单个数组元素,而非拆分后的两个元素。

内容的提问来源于stack exchange,提问作者James Rowell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:04:52