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.