【发布时间】:2014-02-24 13:02:59
【问题描述】:
我有一个执行大量文件处理的脚本,为了安全起见,使用空字符作为分隔符接收其路径就足够了。
但是,它将所有路径都作为绝对路径处理(省去了一些麻烦),但是出于输出目的,这些路径有点笨拙,所以我想从输出中删除一部分路径。现在,我想到了很多选择,但困难在于以一种对我可能遇到的任意路径安全的方式使用它们,这就是事情变得有点棘手的地方。
这是一个简单的例子:
#!/bin/sh
TARGET="$1"
find "$TARGET" -print0 | while IFS= read -rd '' path; do
# Process path for output here
path_str="$path"
echo "$path_str"
done
因此,在上面的脚本中,我想以最兼容的方式(例如 - 没有特定于 bash 的方式)从其中删除 path 并从中删除 TARGET,它需要能够删除 only em> 从字符串的开头,即 - /foo/bar 变为 bar,/foo/bar/foo 变为 bar/foo 和 /bar/foo 仍然是 /bar/foo。它还应该处理文件名中任何可能的字符,包括一些文件系统支持的字符,如波浪线、冒号等,以及讨厌的倒引号字符。
我使用sed 拼凑了一些混乱的解决方案,首先转义任何可能破坏我的正则表达式的字符,但这是一种非常混乱的做事方式,所以我希望有一些更简单的方法.如果没有,到目前为止的解决方案如下:
SAFE_CHARS='s:\([[/.*]\):\\\1:g'
target_safe=$(printf '%s' "$TARGET" | sed "$SAFE_CHARS")
path_str=$(printf '%s' "$path" | sed "s/^$target_safe//g')
除了那些字符之外,我可能还缺少一些我应该转义的字符,并对任何拼写错误表示歉意。
【问题讨论】:
-
read的-d选项是bash特定的(或者至少不是 POSIX 标准的一部分)。如果你使用它,你也可以使用其他bash扩展。