Her parametreden sondaki eğik çizgiyi kaldırmanın en basit yolu nedir?


98

rsyncDizinleri ada göre kopyalamak için '$ @' dizisindeki her parametreden sondaki eğik çizgiyi kaldırmanın en basit yolu nedir ?

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

Açıklama için başlık değiştirildi. Birden fazla eğik çizgi hakkındaki yorumları ve yanıtları anlamak için düzenleme geçmişine bakın.


Yanıtlar:


160

Burada${parameter%word} ayrıntılı olarak verilen genişletmeyi kullanabilirsiniz . İşte davranışı gösteren basit bir test komut dosyası:

#!/bin/bash

# Call this as:
#   ./test.sh one/ two/ three/ 
#
# Output:
#  one two three

echo ${@%/}

35
+1: Son derece bilgiçlikçi olmak gerekirse, bu tek bir eğik çizgiyi kaldıracaktır, tüm eğik çizgileri değil. Sondaki herhangi bir sayıda eğik çizgiyi kaldırmak için:shopt -s extglob; echo "${@%%+(/)}"
glenn jackman

24
Uyarı: Her durumda sondaki eğik çizgileri kaldırmak istemeyebilirsiniz. Bağımsız değişken olarak "/" sağlanırsa, sondaki bölü çizgisinin kaldırılması ... talihsiz sonuçlar doğuracaktır.
Gordon Davisson

13
PROTİP: tr -s /Yinelenen eğik çizgileri ve ardından sondaki eğik çizgiyi kaldırmak için değişken normal ifadeyle birleştirin . örneğinDIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
Dave

1
Gerçekten mi? Bir bash isteminde koş set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"ve bana ne gördüğünü söyle
glenn jackman

1
@twalberg OP'nin yorum başlıklarındaki sorusuna sadece alternatif cevaplar olmayan "protipleri" takdir ediyorum.
Kyle Strand

39

Kabul edilen yanıt, sondaki bir bölü çizgisini keser.

Birden fazla eğik çizgiyi kesmenin bir yolu şudur:

VALUE=/looks/like/a/path///

TRIMMED=$(echo $VALUE | sed 's:/*$::')

echo $VALUE $TRIMMED

Hangi çıktılar:

/looks/like/a/path/// /looks/like/a/path

1
Olasılığına karşı, değişkenleri alıntı unutmayın onlar beyazboşluk: TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
Tetsujin

1
Aslında $()yapının içinde bu gerekli değildir . Bununla birlikte, aynı zamanda zararsızdır :) bu nedenle, çift tırnak işaretlerini "$VALUE"ne zaman kullanıp ne zaman kullanmayacağınıza karar vermenize gerek kalmaması için muhtemelen çift tırnak kullanmak iyi bir uygulamadır .
Chris Johnson

Bunu daha önceki bir çekimle birleştirmenin bir yolu var mı? Protokolü ve (varsa) bir URL'nin sonundaki eğik çizgiyi çıkarmak istiyorum, ancak echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'çalışmıyor (çünkü yakalama grubu sondaki eğik çizgiyle de eşleşiyor sanırım). Bunu iki komutla yapabilirim: echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'ancak bir komutla yapılıp yapılamayacağını merak ettiniz mi?
Adam

Bu cevap, çok büyük bir girdi dosyasıyla benim için daha iyi çalıştı. Basit bir sed 's:/*$::' < in.txt > out.txtişi saniyeler içinde yapar
MitchellK

22

Bu benim için çalışıyor: ${VAR%%+(/)}

Burada açıklandığı gibi http://wiki.bash-hackers.org/syntax/pattern

Extglob kabuk seçeneğini ayarlamanız gerekebilir. Benim için etkin olduğunu göremiyorum ama hala çalışıyor


2
Bir ayarı sorgulamak için: shopt extglobseçenek olmadan
glenn jackman

Bu Genişletilmiş Kalıp Dilidir ve ayarlamanız gerekirextglob .
ingyhere

1
Bu, Mac OS X'in yerleşik bash'ında çalışmaz. Yukarıdaki Sean Bright'ın çözümü:${VAR%/}
Alec Jacobson

13

realpathverilen yolu çözer. Diğer şeylerin yanı sıra, sondaki eğik çizgileri de kaldırır. -sAşağıdaki simlinkleri önlemek için kullanın

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

1
Sonuncusu hariç yoldaki tüm düğümleri gerektirir. Kullanıcı varolmayan bir yola atarsa realpath, başarısız olur.
Livy

2
@Livy realpath --canonicalize-missing, yolun mevcut olmayan herhangi bir kısmıyla kesinlikle doğru şekilde çalışır
maoizm

ve realpath bazı platformlarda eksik :-(
Mark Ribau

8

Bilginize, SO'da .bash_profilebulunan cevaplara dayanarak bu iki işlevi kendime ekledim . Chris Johnson'ın dediği gibi, tüm cevaplar ${x%/}sadece bir bölü çizgisini kaldırır, bu işlevler söylediklerini yapar, umarım faydalı olur.

rem_trailing_slash() {
    echo "$1" | sed 's/\/*$//g'
}

force_trailing_slash() {
    echo "$(rem_trailing_slash "$1")/"
}

4

Gelen zsh kullanabilirsiniz :adeğiştirici.

export DIRECTORY='/some//path/name//'

echo "${DIRECTORY:a}"

=> /some/path/name

Bu realpath, eksik dosyalar / dizinler gibi davranır ancak bağımsız değişken olarak başarısız olmaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.