Apa cara termudah untuk menghapus garis miring dari setiap parameter?

98

Apa cara paling sederhana untuk menghapus garis miring dari setiap parameter dalam larik '$ @', sehingga rsyncmenyalin direktori berdasarkan nama?

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

Judul telah diubah untuk klarifikasi. Untuk memahami komentar dan jawaban tentang beberapa garis miring, lihat riwayat edit.

sid_com
sumber
2
kemungkinan duplikat Hapus garis miring dari ujung variabel
Warren Dew

Jawaban:

160

Anda dapat menggunakan ${parameter%word}perluasan yang dijelaskan di sini . Berikut ini skrip pengujian sederhana yang mendemonstrasikan perilaku tersebut:

#!/bin/bash

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

echo ${@%/}
Sean Bright
sumber
35
+1: Untuk menjadi sangat bertele-tele, itu akan menghapus satu garis miring, tidak semua garis miring. Untuk menghapus sejumlah garis miring:shopt -s extglob; echo "${@%%+(/)}"
glenn jackman
24
Peringatan: Anda mungkin tidak ingin menghapus garis miring di semua kasus. Jika "/" diberikan sebagai argumen, menghapus garis miring akan memiliki ... konsekuensi yang tidak menguntungkan.
Gordon Davisson
13
PROTIP: Gabungkan tr -s /dengan variabel regex untuk menghapus garis miring berulang kemudian menghapus garis miring. misalnyaDIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
Dave
1
Betulkah? Pada prompt pesta, lari set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"dan beri tahu saya apa yang Anda lihat
glenn jackman
1
@twalberg Saya menghargai "protips" yang bukan hanya jawaban alternatif untuk pertanyaan OP di utas komentar.
Kyle Strand
39

Jawaban yang diterima akan memangkas SATU garis miring.

Salah satu cara untuk memangkas beberapa garis miring adalah seperti ini:

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

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

echo $VALUE $TRIMMED

Output mana:

/looks/like/a/path/// /looks/like/a/path
Chris Johnson
sumber
1
Jangan lupa untuk mengutip variabel Anda, jika variabel tersebut berisi spasi: TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
tetsujin
1
Sebenarnya itu tidak perlu di dalam $()konstruksi. Namun itu juga tidak berbahaya :) jadi mungkin praktik yang baik untuk menggunakan tanda kutip ganda seperti "$VALUE"sehingga Anda tidak perlu memutuskan kapan dan kapan tidak menggunakan tanda kutip ganda.
Chris Johnson
Adakah cara untuk menggabungkan ini dengan jepretan sebelumnya? Saya ingin menghapus protokol dan (jika ada) garis miring dari URL tetapi echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'tidak berfungsi (karena grup penangkapan cocok dengan garis miring juga saya kira). Saya bisa melakukannya dengan dua perintah: echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'tetapi bertanya-tanya apakah itu bisa dilakukan dengan satu perintah ?
Adam
Jawaban ini bekerja lebih baik untuk saya dengan file input yang sangat besar. Orang sederhana sed 's:/*$::' < in.txt > out.txtmelakukan pekerjaan dalam hitungan detik
MitchellK
22

Ini bekerja untuk saya: ${VAR%%+(/)}

Seperti dijelaskan di sini http://wiki.bash-hackers.org/syntax/pattern

Mungkin perlu menyetel opsi shell extglob. Saya tidak dapat melihatnya diaktifkan untuk saya tetapi masih berfungsi

Ivan
sumber
2
Untuk menanyakan pengaturan: shopt extglobtanpa opsi
glenn jackman
Ini adalah Extended Pattern Language dan Anda harus mengaturnya extglob.
ingyhere
1
Ini tidak berfungsi pada bash bawaan Mac OS X. Solusi dari Sean Bright di atas adalah:${VAR%/}
Alec Jacobson
13

realpathmenyelesaikan jalur yang diberikan. Antara lain itu juga menghilangkan garis miring yang tertinggal. Gunakan -suntuk mencegah simlinks berikut

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
czerny.dll
sumber
1
Ini membutuhkan semua node di jalur kecuali yang terakhir ada. Jika pengguna melempar di beberapa jalur non-keberadaan, realpathakan gagal.
Livy
2
@Livy realpath --canonicalize-missingbekerja benar-benar benar dengan bagian jalur yang tidak ada
maoizm
dan realpath hilang di beberapa platform :-(
Mark Ribau
8

FYI, saya menambahkan dua fungsi ini ke saya .bash_profileberdasarkan jawaban yang ditemukan di SO. Seperti yang dikatakan Chris Johnson, semua jawaban menggunakan ${x%/}hanya menghapus satu garis miring, fungsi-fungsi ini akan melakukan apa yang mereka katakan, semoga ini berguna.

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

force_trailing_slash() {
    echo "$(rem_trailing_slash "$1")/"
}
Jonathan H.
sumber
4

Dalam zsh Anda dapat menggunakan :apengubah.

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

echo "${DIRECTORY:a}"

=> /some/path/name

Ini bertindak seperti realpathtetapi tidak gagal dengan file / direktori yang hilang sebagai argumen.

Nicolai Fröhlich
sumber