从“$@”数组中的每个参数中删除尾随斜杠的最简单方法是什么,以便
rsync
按名称复制目录?
rsync -a --exclude='*~' "$@" "$dir"
为了澄清起见,标题已更改。要了解有关多个尾部斜杠的评论和答案,请参阅编辑历史记录。
您可以使用
${parameter%word}
扩展,详细信息请参阅此处。这是一个演示该行为的简单测试脚本:
#!/bin/bash
# Call this as:
# ./test.sh one/ two/ three/
#
# Output:
# one two three
echo ${@%/}
接受的答案将修剪一个尾部斜杠。
修剪多个尾部斜杠的一种方法如下:
VALUE=/looks/like/a/path///
TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
echo "$VALUE" "$TRIMMED"
哪个输出:
/looks/like/a/path/// /looks/like/a/path
这对我有用:
${VAR%%+(/)}
如此处所述 http://wiki.bash-hackers.org/syntax/pattern
可能需要设置 shell 选项 extglob。我看不到它为我启用,但它仍然有效
realpath
解析给定路径。除此之外,它还删除了尾部斜杠。使用 -s
防止跟随 simlinks
DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
仅供参考,我根据在 SO 上找到的答案将这两个函数添加到我的
.bash_profile
中。正如 Chris Johnson 所说,所有使用 ${x%/}
的答案仅删除一个斜杠,这些函数将按照他们所说的进行操作,希望这有用。
rem_trailing_slash() {
echo "$1" | sed 's/\/*$//g'
}
force_trailing_slash() {
echo "$(rem_trailing_slash "$1")/"
}
在 zsh 中,您可以使用
:a
修饰符。
export DIRECTORY='/some//path/name//'
echo "${DIRECTORY:a}"
=> /some/path/name
这与
realpath
类似,但不会因缺少文件/目录作为参数而失败。
我在修剪用于
rsync
的目录参数时使用的方法,这里使用 dirname
和 basename
来分割路径,然后重新组合不带尾部斜杠的部分。
raw_dir=/a/b/c/
trim_dir=$(dirname "$raw_dir")"/"$(basename "$raw_dir")
注意已接受答案中的一些评论:
//[...]
替换所有重复的斜杠/
(根据@Dave评论)/
)(根据@GordonDavisson评论)trimSlash() { for s; do sed -E 's://*:/:g; s:(^/)?/*$:\1:' <<< "${s}"; done; }
不如使用参数替换的答案那么简洁,但我认为值得付出努力。
一些测试用例:
$ trimSlash "/" "///" "a/" "a/a/" "a///a/" "a/a" "a///a" "a///" "/a/a/" "///a///"
/
/
a
a/a
a/a
a/a
a/a
a
/a/a
/a
完全符合 POSIX
# recursively remove trailing slashes
remove_slashes() {
res="${1%/}"
if [ "$1" = "$res" ]
then echo "$res"
else remove_slashes "$res"
fi
}
# test:
remove_slashes a/b/
remove_slashes a/b////
remove_slashes ""
remove_slashes ///
remove_slashes ///a
不是最漂亮的方式,但又快又简单。
我只是添加一个斜线并删除所有双打。假设在其他地方找不到这样的模式。
WORD="abc/"
WORD=$WORD'/'
WORD=`echo $WORD | sed s/'\/\/'/''/g`
echo $WORD