首页 > 解决方案 > 如何在 Shell 脚本中为空格分隔字符串中的子字符串添加前缀

问题描述

我有一个以空格分隔的文件字符串,这些文件可能以也可能不以“/”为前缀(即它们的路径相对于给定的根目录):

mydirs='a /b/c /d/e/f g /h/i'

我需要在每个文件前面加上用户提供的根目录。我需要一种可移植的方式来做到这一点(不用说我更喜欢速度,所以欢迎内置)。所以我们都在同一个页面上,“便携”是指“可移植到不同的 linux shell(sh、bash、ksh、zsh、tsh、csh 等)”

目前,我的解决方案是:

root="my_root"  # User-supplied root directory

prefixed_dirs=`echo $mydirs |
tr ' ' '
' | sed 's;^/*;prefix/;' | tr '
' ' '`

这也在我的行尾放了一个空格,这不是我想要的。

我想要的输出将是带有前缀文件的单行回显给我,如下所示:

my_root/a my_root/b/c my_root/d/e/f my_root/g my_root/h/i

我已经尝试过搜索答案,但我还没有真正找到我正在寻找的东西(如果有解决方案,请指出我的解决方案)。我知道 sed 默认在新行上运行,所以我实际上是在尝试让 sed 在子字符串的开头运行(我不能只查找空格,因为它会a在上面跳过)。

这行得通,但语法很难看。有没有更简洁的方法来做到这一点(再次,同时保持可移植性)?也许是干净的awkperl单衬里(同样,必须是便携式的)?干净的 sed 单衬里加倍积分!

非常感谢!

标签: stringshellportability

解决方案


您可以使用该set命令将字符串成分设置为位置参数,然后运行 ​​POSIX 支持的参数扩展技术以删除前导(/如果存在)。

请注意,set在未引用的变量扩展上使用也会受到全局扩展的影响。确保没有发生这种情况的余地。

root="my_root"
mydirs='a /b/c /d/e/f g /h/i'

set -- $mydirs

for arg; do 
  printf '%s ' "${root}/${arg#/}"
done

或者,如果您预计会发生 glob 扩展,请在 set 命令周围加上set -fandset +f以禁用和启用 glob 扩展。


推荐阅读