从每个参数中删除尾部斜杠的最简单方法是啥?
Posted
技术标签:
【中文标题】从每个参数中删除尾部斜杠的最简单方法是啥?【英文标题】:What is the simplest way to remove a trailing slash from each parameter?从每个参数中删除尾部斜杠的最简单方法是什么? 【发布时间】:2012-02-19 13:58:15 【问题描述】:从“$@”数组中的每个参数中删除尾部斜杠以便rsync
按名称复制目录的最简单方法是什么?
rsync -a --exclude='*~' "$@" "$dir"
为澄清起见,已更改标题。要了解 cmets 并回答有关多个尾部斜杠的问题,请参阅编辑历史记录。
【问题讨论】:
Remove slash from the end of a variable 的可能重复项 【参考方案1】:您可以使用详细说明为here 的$parameter%word
扩展。这是一个演示该行为的简单测试脚本:
#!/bin/bash
# Call this as:
# ./test.sh one/ two/ three/
#
# Output:
# one two three
echo $@%/
【讨论】:
+1:为了高度迂腐,这将删除单个斜杠,而不是所有尾随斜杠。要删除任意数量的尾部斜杠:shopt -s extglob; echo "$@%%+(/)"
警告:您可能不想在所有情况下都删除尾部斜杠。如果“/”作为参数提供,删除尾部斜杠将产生......不幸的后果。
PROTIP:将tr -s /
与变量正则表达式组合以删除重复的斜杠,然后删除尾部斜杠。例如DIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=$DIR%/
真的吗?在 bash 提示符下,运行 set -- one///// two// three four/; shopt -s extglob; echo "$@%%+(/)"
并告诉我你看到了什么
@twalberg 我很欣赏“protips”,它们不仅仅是评论线程中 OP 问题的替代答案。【参考方案2】:
这对我有用:$VAR%%+(/)
如此处所述http://wiki.bash-hackers.org/syntax/pattern
可能需要设置 shell 选项 extglob。我看不到它已为我启用,但它仍然有效
【讨论】:
查询设置:shopt extglob
无选项
这是扩展模式语言,您必须设置extglob
。
这不适用于 Mac OS X 的内置 bash。上面 Sean Bright 的解决方案是:$VAR%/
【参考方案3】:
接受的答案将修剪一个尾部斜杠。
修剪多个尾部斜杠的一种方法是这样的:
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:/*$::')
实际上在 $()
构造中没有必要这样做。但是它也是无害的 :) 所以使用像"$VALUE"
这样的双引号可能是一个好习惯,这样您就不必决定何时以及何时不使用双引号。
有什么方法可以将它与早期的捕获相结合?我想从 URL 中删除协议和(如果存在)尾部斜杠,但 echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'
不起作用(因为我猜捕获组也匹配尾部斜杠)。我可以用两个命令做到这一点:echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'
但想知道是否可以用一个命令完成?
这个答案对我来说效果更好,输入文件很大。一个简单的sed 's:/*$::' < in.txt > out.txt
在几秒钟内完成这项工作【参考方案4】:
在 zsh 中,您可以使用 :a
修饰符。
export DIRECTORY='/some//path/name//'
echo "$DIRECTORY:a"
=> /some/path/name
这类似于realpath
,但不会因缺少文件/目录作为参数而失败。
【讨论】:
【参考方案5】:仅供参考,我根据在 SO 上找到的答案将这两个函数添加到了我的 .bash_profile
。正如 Chris Johnson 所说,所有使用 $x%/
的答案都只删除一个斜线,这些函数会按照他们说的做,希望这很有用。
rem_trailing_slash()
echo "$1" | sed 's/\/*$//g'
force_trailing_slash()
echo "$(rem_trailing_slash "$1")/"
【讨论】:
【参考方案6】:realpath
解析给定路径。除其他外,它还删除了尾部斜杠。使用-s
防止以下simlinks
DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
【讨论】:
它要求路径中除了最后一个节点之外的所有节点都存在。如果用户抛出一些不存在的路径,realpath
将失败。
@Livy realpath --canonicalize-missing
与路径的任何不存在部分完全正确
某些平台上缺少 realpath :-(【参考方案7】:
不是最漂亮的方式,但又快又简单。
我只是添加一个斜线并删除所有双打。假设这种模式不会在其他地方找到。
WORD="abc/"
WORD=$WORD'/'
WORD=`echo $WORD | sed s/'\/\/'/''/g`
echo $WORD
【讨论】:
【参考方案8】:在接受的答案中记下几个 cmets:
-
将所有重复的斜杠
//[...]
替换为单个斜杠 /
(根据 @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
【讨论】:
以上是关于从每个参数中删除尾部斜杠的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
MySQL:从 MySQL TABLE 中删除重复行的最安全方法是啥?