1

按照我在这里找到的内容,我尝试将某种模式的文件列表拆分为一个数组。但是,字符串不会拆分(空行只是为了便于阅读)。

bash-3.2$ files=jfn240_463.o*
bash-3.2$ echo $files
jfn240_463.o9017306 jfn240_463.o9075989 jfn240_463.o9281439 jfn240_463.o9287196

bash-3.2$ IFS=' ' read -ra ll <<< $files
bash-3.2$ echo $ll
jfn240_463.o9017306 jfn240_463.o9075989 jfn240_463.o9281439 jfn240_463.o9287196

bash-3.2$ IFS=' ' read -ra ll <<< "$files"
bash-3.2$ echo $ll
jfn240_463.o9017306 jfn240_463.o9075989 jfn240_463.o9281439 jfn240_463.o9287196

bash-3.2$ echo ${ll[@]}
jfn240_463.o9017306 jfn240_463.o9075989 jfn240_463.o9281439 jfn240_463.o9287196

bash-3.2$ echo ${ll[1]}

bash-3.2$ 

我确定我会得到一个数组,那为什么不呢?

编辑:

我尝试使用find,但没有取得多大成功。

bash-3.2$ files=$(find jfn240_463.o*)
bash-3.2$ echo ${files[0]}
jfn240_463.o9017306 jfn240_463.o9075989 jfn240_463.o9281439 jfn240_463.o9287196
bash-3.2$ 
bash-3.2$ IFS=' ' read -ra ll <<< $files
bash-3.2$ echo ${ll[@]}
jfn240_463.o9017306
bash-3.2$ 
4

2 回答 2

2

问题是它$files包含"jfn240_463.o*"不是一堆由空格分隔的文件名。你不能用空格来分割它,因为里面甚至没有空格。首先使用数组:

ll=(jfn240_463.o*)
于 2013-08-07T09:05:47.777 回答
0

Ignacio Vazquez-Abrams的问题完全正确:当您定义:

$ files=jfn240_463.o*

shell 不扩展*“路径名扩展”)。当你写:

$ echo $files

外壳确实扩展了*. 要查看 的实际值$files,您需要编写:

$ echo "$files"
jfn240_463.o*

所以$files里面没有空格。

您可能期望同样适用于<<<,但事实证明 bash 不区分<<<$filesand <<<"$files",因为 bash 不会对后面的单词进行路径名扩展<<<。您可以通过键入来查看这一点,例如:

$ cat <<<jfn240_463.o*
jfn240_463.o*

<<<$files(其实和有一点区别<<<"$files"。bash 对后面的词进行参数扩展、命令扩展和算术扩展<<<,在这种情况下$files,如果没有引用这个词,它也会进行分词。但是,在分词之后完成后,单词再次连接在一起,由单个空格分隔。因此,在未引用的情况下,所有空格序列都减少为单个空格,而在引用的情况下,空格被精确保留。区别是最大的当$IFS已更改为空格以外的内容时可见。)

正如 Ignacio Vasquez-Abrams 建议的那样,有多种可能的解决方法,其中最简单的是直接设置数组:

ll=(jfn240_463.o*)

(在这种语法中,bash确实执行路径名扩展。)

但是,如果任何文件的名称中有空格,这将失败。如果文件名中没有换行符,另一个简单的解决方案(使用 bash)是使用 mapfile:

mapfile -t ll < <(ls jfn240_463.o*)

或者,使用 bash 内置 printf:

mapfile -t ll < <(printf "%s\n" jfn240_463.o*)

在文件名可能包含任意字符(除了不能出现在文件名中的\0and之外)的情况下,让它工作绝非易事。/

于 2013-08-07T17:42:51.377 回答