Cách đơn giản nhất để xóa dấu gạch chéo khỏi mỗi tham số là gì?


97

Cách đơn giản nhất để xóa dấu gạch chéo khỏi mỗi tham số trong mảng '$ @' để rsyncsao chép các thư mục theo tên là gì?

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

Tiêu đề đã được thay đổi để làm rõ. Để hiểu các nhận xét và câu trả lời về nhiều dấu gạch chéo sau, hãy xem lịch sử chỉnh sửa.


Câu trả lời:


160

Bạn có thể sử dụng phần ${parameter%word}mở rộng được trình bày chi tiết tại đây . Đây là một tập lệnh thử nghiệm đơn giản thể hiện hành vi:

#!/bin/bash

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

echo ${@%/}

35
+1: Có tính ngữ nghĩa cao, điều đó sẽ loại bỏ một dấu gạch chéo, không phải tất cả các dấu gạch chéo theo sau. Để loại bỏ bất kỳ số lượng dấu slashes:shopt -s extglob; echo "${@%%+(/)}"
glenn Jackman

24
Cảnh báo: bạn có thể không muốn xóa dấu gạch chéo trong mọi trường hợp. Nếu "/" được cung cấp như một đối số, bỏ dấu gạch chéo ở cuối sẽ gây ra ... hậu quả đáng tiếc.
Gordon Davisson

13
MẸO: Kết hợp tr -s /với biến regex để loại bỏ dấu gạch chéo lặp lại sau đó loại bỏ dấu gạch chéo. ví dụDIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
Dave

1
Có thật không? Tại một bash nhanh chóng, chạy set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"và cho tôi biết những gì bạn thấy
glenn Jackman

1
@twalberg Tôi đánh giá cao "lời khuyên" không chỉ là câu trả lời thay thế cho câu hỏi của OP trong chuỗi nhận xét.
Kyle Strand

39

Câu trả lời được chấp nhận sẽ cắt MỘT dấu gạch chéo.

Một cách để cắt bỏ nhiều dấu gạch chéo ở cuối như sau:

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

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

echo $VALUE $TRIMMED

Kết quả đầu ra:

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

1
Đừng quên để báo các biến của bạn, trong trường hợp họ được chứa khoảng trắng: TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
Tetsujin

1
Trên thực tế, điều đó không cần thiết bên trong $()cấu trúc. Tuy nhiên nó cũng vô hại :) vì vậy có lẽ bạn nên sử dụng dấu ngoặc kép như thế nào "$VALUE"để bạn không phải quyết định khi nào nên và khi nào không nên sử dụng dấu ngoặc kép.
Chris Johnson

Có cách nào để kết hợp điều này với một lần chụp trước đó không? Tôi muốn loại bỏ giao thức và (nếu có) dấu gạch chéo khỏi URL nhưng echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'không hoạt động (vì nhóm nắm bắt cũng khớp với dấu gạch chéo theo tôi đoán). Tôi có thể làm điều đó với hai lệnh: echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'nhưng tự hỏi liệu nó có thể được thực hiện với một lệnh không?
Adam

Câu trả lời này hoạt động tốt hơn đối với tôi với một tệp đầu vào rất lớn. Một đơn giản sed 's:/*$::' < in.txt > out.txtthực hiện công việc trong vài giây
MitchellK

22

Điều này phù hợp với tôi: ${VAR%%+(/)}

Như được mô tả tại đây http://wiki.bash-hackers.org/syntax/pattern

Có thể cần đặt extglob tùy chọn shell. Tôi không thể thấy nó được bật cho tôi nhưng nó vẫn hoạt động


2
Để truy vấn một khung cảnh: shopt extglobkhông có tùy chọn
glenn Jackman

Đây là Ngôn ngữ Mẫu mở rộng và bạn phải đặt extglob.
ingyhere

1
Điều này không hoạt động trên cơ sở cài đặt sẵn của Mac OS X. Các giải pháp của Sean Bright trên không:${VAR%/}
Alec Jacobson

13

realpathgiải quyết đường dẫn đã cho. Trong số những thứ khác, nó cũng loại bỏ các dấu gạch chéo. Sử dụng -sđể ngăn các liên kết sim sau

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

1
Nó yêu cầu tất cả các nút trong đường dẫn ngoại trừ nút cuối cùng tồn tại. Nếu người dùng ném vào một số đường dẫn không tồn tại, realpathsẽ không thành công.
Livy,

2
@Livy realpath --canonicalize-missinghoạt động hoàn toàn chính xác với bất kỳ phần nào không tồn tại của đường dẫn
maoizm

và realpath bị thiếu trên một số nền tảng :-(
Mark Ribau

8

FYI, tôi đã thêm hai chức năng này vào của mình .bash_profiledựa trên các câu trả lời được tìm thấy trên SO. Như Chris Johnson đã nói, tất cả các câu trả lời sử dụng ${x%/}chỉ loại bỏ một dấu gạch chéo, các hàm này sẽ thực hiện những gì chúng nói, hy vọng điều này hữu ích.

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

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

4

Trong zsh, bạn có thể sử dụng công cụ :asửa đổi.

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

echo "${DIRECTORY:a}"

=> /some/path/name

Điều này hoạt động giống như realpathnhưng không thất bại với các tệp / thư mục bị thiếu làm đối số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.