【问题标题】:How do I split a list of unquoted paths with embedded spaces into individual paths?如何将带有嵌入空格的未引用路径列表拆分为单独的路径?
【发布时间】:2014-06-19 14:37:47
【问题描述】:

我不擅长在 Ubuntu 中编写 bash shell 脚本,所以我需要你的帮助。

问题是……

我们将 Perforce 用于 SCM。

我尝试从//Development/ 分支获取目录。

到目前为止,一切都很好。

但现在我不能再用空格分割分支了,因为分支如下(注意嵌入的空间):

//Development/graphic/release/Unity Provider

我们需要将每个分支放在以//Development 开头的单独行上,但我总是得到以下结果(注意不需要的换行符):

//开发/图形/发布/Unity
提供者

我该如何解决这个问题?

请帮助我。 谢谢。

下面是一个示例单行字符串:

//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager

而且,我想得到一个如下所示的结果字符串(每个分支名称都在自己的行上):

//Development/graphic/release/CM 
//Development/graphic/release/GManager 
//Development/graphic/release/Notification 
//Development/graphic/release/Core 
//Development/graphic/release/Provider 
//Development/graphic/release/WH 
//Development/graphic/release/Accessory 
//Development/graphic/release/Unity Provider 
//Development/graphic/release/tipManager

我还想将结果存储在列表变量中。

例如,list[0] 应该包含 //Development/graphic/release/CM

【问题讨论】:

  • 你的预期输出是什么?
  • 您如何确定目录?可以不把目录重命名为Unity-Provider,避免路径名中空格的痛苦吗?

标签: string bash shell divide


【解决方案1】:

我假设:

  • 您希望根据以//[Development/] 开头的子字符串将输入字符串拆分为单独的路径,或者在字符串的开头,或者如果在字符串的开头,则在前面有一个空格。
  • 无论//[Development/] 实例之间的字符串是否包含空格。
str='//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager'    

echo "$str" | sed 's# \(//\)#\'$'\n''\1#g'

以上内容应该适用于任何与 POSIX 兼容的 sed 实现。

要在变量中捕获输出,使用command substitution

result=$(echo "$str" | sed 's# \(//\)#\'$'\n''\1#g')

如果你想逐行处理结果:

while read -r path; do echo "$path"; done <<<"$result"

sed 命令解释:

  • # 被任意选择为seds(字符串替换)命令的分隔符,以便更容易匹配/ 字符(通常,/ 用作分隔符,其中将需要 \-escaping / 在正则表达式和替换字符串中的实例)。
  •  \(//\) 匹配 // 如果前面有空格,即在字符串内部。
  • \'$'\n'' 使用 ANSI C 引用有效地将换行符 (\n) 插入到替换字符串中(OSX 兼容性所需;在 Linux 上,只需 \n 即可)。
  • \1 从正则表达式中插入第一个(也是唯一的)捕获组,即//
  • g 确保匹配是全局,即替换匹配正则表达式的所有子字符串。

结果:

//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager

【讨论】:

  • 感谢您的帮助,但我无法在 sed cmd 中使用 -E 选项。我认为这个操作系统是redhat
  • @user3754723:我明白了。我刚刚更新了我的答案以使其与 POSIX 兼容,这应该对你有用 - 如果它没有,请告诉我。
  • 非常感谢,还有...我还有一个问题...:) 如何将它存储到变量中? list=echo "$str" | sed 's# \(//\)#\'$'\n''\1#g' 我想要的不起作用。我想将其存储到列表中。
  • @user3754723 不客气;在变量中重新捕获输出:查看我的更新。
  • 好吧,我仍然必须得到相同的结果 :( for element in $result do echo $element done 抱歉,我无法使用新行进行漂亮的评论 :(
【解决方案2】:

使用内部字段分隔符 (IFS) 变量以换行符代替空格。

这很好地解释了它: http://mindspill.net/computing/linux-notes/using-the-bash-ifs-variable-to-make-for-loops-split-with-non-whitespace-characters/

从上面的链接中提取的示例:

#!/bin/bash
IFS=$','
vals='/mnt,/var/lib/vmware/Virtual Machines,/dev,/proc,/sys,/tmp,/usr/portage,/var/tmp'
for i in $vals; 
     do echo $i; 
done
unset IFS

【讨论】:

  • 重新术语:换行符也是空格(white space)的一种形式。 OP 的示例输入是 one-line 字符串,因此不适用换行符分割。
【解决方案3】:

你也可以试试这个 awk 命令,

$ awk -v RS=" //" '{gsub (/^D/,"//D");}1' file
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager 

【讨论】:

  • No No~ 我想像下面那样做: //Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/图形/发布/核心 //开发/图形/发布/提供者 //开发/图形/发布/WH //开发/图形/发布/附件 //开发/图形/发布/Unity Provider //开发/图形/发布/提示管理器
  • 在您的问题中发表上述评论。
猜你喜欢
  • 2014-09-04
  • 2012-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多