【问题标题】:Split string into array (delimited by "\ ")将字符串拆分为数组(以“\”分隔)
【发布时间】:2014-09-11 14:22:42
【问题描述】:

我目前正在编写一个 bash 脚本。假设我有以下字符串:

C:\Program Files\Folder1\ C:\Program Files\Folder2\ C:\Program Files\Folder3\ 

此字符串可以包含未知数量的窗口位置。 现在我需要在每个位置的末尾将字符串拆分成一个数组,因此每个位置在数组中都有自己的键。主要问题是每个路径(程序文件)中的空格。

到目前为止我已经尝试过:

使用 IFS 变量:

oldIFS="$IFS"
IFS="\ "
myArray=( $myString )
IFS="$oldIFS"

这里的问题是,它会削减每个反斜杠上的位置,而不仅仅是反斜杠和空格。所以C: 是我数组的第一个元素。

使用读取命令:

IFS="\ " read -ra myArray "$myString"

和以前一样的问题。

关于如何解决这个问题的任何想法?

编辑:我不是在使用真正的 bash,而是在 windows 上使用 git bash。所以不是每个 bash 命令都可用。

【问题讨论】:

  • 不,因为计算机不是通灵的。
  • bashWindowsWindows 样式路径?
  • 我的错,我编辑了字符串,所以现在应该清楚我想要做什么了。
  • 是的。我对此也不满意,但我得到了创建 bash 脚本的命令,该脚本可以部分执行我的要求(用例将是 Windows 上的 git bash)
  • IFS 中的所有字符都被视为字段分隔符。这意味着 bash 将在出现任何反斜杠或空格时拆分字符串。我相信您必须采用另一种拆分字符串的方法,即使用 sed 或类似方法对其进行预处理,以便将 \ 转换为可以放入 IFS 的单个字符。

标签: arrays regex bash shell


【解决方案1】:

你可以使用这个脚本:

s='C:\Program Files\Folder1\ C:\Program Files\Folder2\ C:\Program Files\Folder3\'
IFS='^K' read -ra arr < <(sed 's/\\ /^K/g' <<< "$s")

或非 BASH

echo "$s" | sed 's/\\ /^K/g' | IFS='^K' read -ra arr

测试:

declare -p arr
declare -a arr='([0]="C:\\Program Files\\Folder1" [1]="C:\\Program Files\\Folder2" [2]="C:\\Program Files\\Folder3\\")'

PS:这里^K其实是ControlVK


你也可以使用awk:

echo "$s" | awk -F '\\\\( |$)' '{for (i=1; i<=NF; i++) if ($i) print $i}'
C:\Program Files\Folder1
C:\Program Files\Folder2
C:\Program Files\Folder3

创建数组:

IFS=';' arr=($(echo "$s" | awk -F '\\\\( |$)' -v ORS=';' '{for (i=1; i<=NF; i++) 
     if ($i) print $i}'))

【讨论】:

  • 这给了我两个不同的错误:cannot make pipe for process substitution: Function not implementedambiguous redirect- 可能是因为我在 windows 上使用 git bash 而不是真正的 bash?
  • 哦,好的,您也可以使用:echo "$s" | sed 's/\\ /^K/g' | IFS='^K' read -ra arr
  • 还在我的回答中添加了awk 版本。
  • 您的非 Bash 版本根本不打印任何内容。 awk 版本有效,但这只会打印项目并且不会将它们放入数组中以备后用。我尝试编辑代码,以便将所有内容都放入一个数组中,但没有运气(没有 awk 技能...)
  • 当您甚至没有标准的 BASH 可以使用时,为什么要将它放在 BASH 数组中。其他基于 read 的命令无法正常工作的原因是因为您的 BASH 功能非常有限,因此 BASH 数组可能无法按您的意愿工作。最好获取 awk 输出并将其存储在临时文件中以供以后处理。
【解决方案2】:

可能没有文件名包含选项卡,以下将起作用:

IFS=$'\t' read -ra the_files <<<"${the_string//\\ /$'\\\t'}"

在文件名确实包含制表符的不太可能的情况下,您可以将上面的制表符更改为其他字符,例如\1

【讨论】:

  • 这很好用......但仅适用于第一个元素。最终数组仅包含一个元素(`C:\Program Files\Folder1`) - 对此有什么想法吗?
  • @JoelP:你如何打印最终的数组?您需要使用printf %s\\n ${the_files[@]}declare -p the_files 来查看其值。
  • 好吧,使用你的 printf 代码我只会得到C:\Program[linebreak]Files\Folder1 作为输出(用真正的换行符替换 [linebreak])。
  • @JoelP:糟糕,我错过了 printf 命令中的引号。在read 命令中应该是printf %s\\n ${the_files[@]}". Did you use -ra`,而不仅仅是-rdeclare -p the_files 给你什么?
  • 换行符现在消失了,但数组仍然只包含一个元素。是的,我确实使用了-ra,但仍然没有成功。因为我在 Windows 上只使用 git bash,所以我无法使用 declare
猜你喜欢
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2011-03-24
相关资源
最近更新 更多