如何从 '$@' 数组的每个参数中最简单地删除尾部斜杠,以便 rsync
按名称复制目录?
rsync -a --exclude='*~' "$@" "$dir"
标题已经更改以进行澄清。要了解有关多个尾随斜杠的评论和答案,请查看编辑历史记录。
如何从 '$@' 数组的每个参数中最简单地删除尾部斜杠,以便 rsync
按名称复制目录?
rsync -a --exclude='*~' "$@" "$dir"
标题已经更改以进行澄清。要了解有关多个尾随斜杠的评论和答案,请查看编辑历史记录。
${parameter%word}
扩展。这是一个演示行为的简单测试脚本:#!/bin/bash
# Call this as:
# ./test.sh one/ two/ three/
#
# Output:
# one two three
echo ${@%/}
shopt -s extglob; echo "${@%%+(/)}"
- glenn jackmantr -s /
命令来删除重复的斜杠,然后删除末尾的斜杠。例如:DIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
- Daveset -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"
,告诉我你看到了什么。 - glenn jackman被接受的答案会删除一个尾随斜线。
删除多个尾随斜线的一种方法是这样的:
VALUE=/looks/like/a/path///
TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
echo "$VALUE" "$TRIMMED"
输出为:
/looks/like/a/path/// /looks/like/a/path
TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
- tetsujin$()
结构中其实不需要这样做,但也没有坏处 :) 所以最好的做法是使用双引号,如 "$VALUE"
,这样就不必决定何时使用双引号和何时不使用。 - Chris Johnsonecho "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'
不起作用(因为捕获组也匹配尾部斜杠)。我可以用两个命令完成它:echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'
但想知道是否可以用一个命令完成? - Adamsed 's:/*$::' < in.txt > out.txt
可以在几秒钟内完成工作。 - MitchellK对我来说,这很有效: ${VAR%%+(/)}
如此处所述 http://wiki.bash-hackers.org/syntax/pattern
可能需要设置shell选项extglob。我看不到它对我启用了,但它仍然有效。
shopt extglob
,无选项。 - glenn jackmanextglob
。 - ingyhere${VAR%/}
- Alec Jacobson${VAR%%/*}
,它删除第一个斜杠到结尾的所有内容(例如,“foo///bar/foobar”变成“foo”)。附言:令人惊讶的是,在Fedora 36中,默认情况下启用了extglob。 - Kevinrealpath
用于解析给定路径。除其他功能外,它还会删除末尾的斜杠。使用 -s
来避免跟随符号链接。
DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
realpath
需要路径中除了最后一个节点以外的所有节点都存在。如果用户输入了一些不存在的路径,realpath
将会失败。 - Livyrealpath --canonicalize-missing
命令能够完全正确地处理路径中任何不存在的部分。 - maoizm提供信息,我根据在SO上找到的答案将这两个功能添加到了我的.bash_profile
中。正如Chris Johnson所说,使用${x%/}
的所有答案仅会删除一个斜杠,而这些功能将执行它们所说的操作,希望这对您有用。
rem_trailing_slash() {
echo "$1" | sed 's/\/*$//g'
}
force_trailing_slash() {
echo "$(rem_trailing_slash "$1")/"
}
: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
这不是最美观的方式,但快捷简便。
我只需添加一条斜杠并删除所有双重的部分。假设这样的模式不会在其他地方被找到。
WORD="abc/"
WORD=$WORD'/'
WORD=`echo $WORD | sed s/'\/\/'/''/g`
echo $WORD
a//b
与a/b
是相同的。因此,在某些情况下,一个人不必删除尾部斜杠。 - Gayan Weerakutti