我有一个执行大量文件处理的脚本,并且使用空字符作为安全分隔符来接收其路径就足够了。
但是,它将所有路径都处理为绝对路径(节省了一些令人头疼的事情),但是这些路径对于输出来说有点笨拙,所以我想从输出中删除一大块路径。现在,我想到了很多选择,但困难在于以一种对我可能遇到的任意路径安全的方式使用它们,这就是事情变得有点棘手的地方。
这是一个简单的例子:
#!/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
因此,在上面的脚本中,我想以尽可能最兼容的方式从path
中删除TARGET
(例如 - 没有特定的bash),它需要能够删除仅从字符串的开头,即 - /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')
除了那些字符之外,可能还有一些字符缺失我应该逃避,并为任何拼写错误道歉。
答案 0 :(得分:1)
从字符串中删除前缀
$ TARGET=/foo/
$ path=/foo/bar
$ echo "${path#$TARGET}"
bar
参数扩展的#
运算符是POSIX标准的一部分,可以在任何符合POSIX的shell中使用。
答案 1 :(得分:0)
您可以尝试这个简单的查找:
export TARGET="$1"
find "$TARGET" -exec bash -c 'sed "s|^$TARGET\/||" <<< "$1"' - '{}' \;