Какой самый простой способ удалить косую черту из каждого параметра?

Какой самый простой способ удалить косую черту из каждого параметра в массиве '$@', чтобы rsync копирует каталоги по имени?

rsync -a --exclude='*~' "$@" "$dir"

Название было изменено для уточнения. Чтобы понять комментарии и ответить о множественных конечных слешах, просмотрите историю редактирования.

9 ответов

Решение

Вы можете использовать ${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

Возможно, потребуется установить параметр оболочки extglob. Я не вижу его включенным для меня, но он все еще работает

realpath разрешает данный путь. Среди прочего он также удаляет косые черты. использование -s предотвратить следующие симлинки

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a

К вашему сведению, я добавил эти две функции .bash_profile на основе ответов, найденных на SO. Как сказал Крис Джонсон, все ответы с использованием ${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")

Taking note of a couple comments in the accepted answer:

  1. Replace all repeated slashes //[...] with a single slash (per @Dave comment)
  2. Remove trailing slash unless it is also the leading slash (i.e., the root filepath /) (per @GordonDavisson comment)
      trimSlash() { for s; do sed -E 's://*:/:g; s:(^/)?/*$:\1:' <<< "${s}"; done; }

Not as concise as the answers using parameter substitution, but I think its worth the diligence.

Some test cases:

      $ 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
Другие вопросы по тегам