【问题标题】:Bash, splitting string failBash,拆分字符串失败
【发布时间】:2013-08-08 13:23:21
【问题描述】:

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

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$ 

【问题讨论】:

    标签: arrays string bash split


    【解决方案1】:

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

    $ files=jfn240_463.o*
    

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

    $ echo $files
    

    shell确实扩展了*。要查看$files的真正价值,你需要这样写:

    $ echo "$files"
    jfn240_463.o*
    

    所以$files 里面没有空格。

    您可能认为&lt;&lt;&lt; 也是如此,但事实证明 bash 无法区分 &lt;&lt;&lt;$files&lt;&lt;&lt;"$files",因为 bash 不会对 &lt;&lt;&lt; 后面的单词进行路径名扩展。您可以通过键入来查看,例如:

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

    (&lt;&lt;&lt;$files&lt;&lt;&lt;"$files"其实有一点区别。bash对&lt;&lt;&lt;后面的单词进行参数扩展、命令扩展和算术扩展,这里是$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*)
    

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

    【讨论】:

      【解决方案2】:

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

      ll=(jfn240_463.o*)
      

      【讨论】:

      • 那么我该如何实现呢?我尝试使用 find 并失败(更新了我的问题)。
      猜你喜欢
      • 2013-01-15
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 2021-10-23
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多