从每个参数中删除尾部斜杠的最简单方法是啥?

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

【讨论】:

以上是关于从每个参数中删除尾部斜杠的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从excel中的字符串中删除单词的最简单方法是啥?

从批处理文件输入中删除尾部斜杠

C# 中从字符串中修剪换行符的最简单方法是啥?

MySQL:从 MySQL TABLE 中删除重复行的最安全方法是啥?

在 MFC 项目中删除对某些 ActiveX 库的依赖的最简单方法是啥?

对多个参数执行“SELECT TOP 5”的最简单方法是啥?