Xây dựng đường dẫn mạnh mẽ


16

Giả sử tôi có một số biến trong tập lệnh shell (ví dụ: trong zsh):

FOLDER_1, FOLDER_2, etc.

Các biến này đề cập đến các thư mục giảm dần từ /. Ví dụ, nếu tôi có một đường dẫn/home/me/stuff/items

các biến sẽ là:

FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'

Bây giờ, nói rằng tôi muốn xây dựng lại đường dẫn tương ứng bằng cách nối các biến. Một cách có thể là xây dựng đường dẫn như sau:

PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/

Tuy nhiên, giả sử rằng một số biến FOLDER_iđi kèm với dấu gạch chéo về phía trước, trong khi các biến khác không (và chúng tôi không biết cái nào), vd

FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'

Câu hỏi của tôi là: Làm thế nào tôi có thể xây dựng con đường mạnh mẽ? (ví dụ: tránh các dấu gạch chéo kép và thêm chúng vào nơi cần thiết).

Tôi nghĩ một cách để làm điều này là thêm /luôn luôn giữa các cặp biến và sau đó xóa bất kỳ bản sao nào sed, nhưng tôi không thể làm cho nó hoạt động (tôi không chắc là mình đang xử lý /chính xác sed).

Ngoài ra, tôi đang phát minh lại bánh xe ? (tức là đã có sẵn trong đó chưa?).

Cuối cùng, nếu các biến nằm trong một mảng , ví dụ FOLDERS, liệu có thể làm điều này mà không cần lặp không? (hoặc cách khác, bằng cách lặp nhưng không biết có bao nhiêu FOLDERStrong mảng).

Câu trả lời:


12

Bạn có thể sử dụng printfvới một mảng:

parts=("$FOLDER_1" "$FOLDER_2" "$FOLDER_3");
printf '/%s' "${parts[@]%/}"
# Use "printf -v path" to save it into a variable called "path" instead of printing it

Các %nhà điều hành Trims trailing chuỗi, trong trường hợp này /. Bằng cách áp dụng nó parts[@], nó cắt riêng từng thành viên mảng.

Chìa khóa để hiểu printfthủ thuật này , là bit này từ man 1 printf: "Chuỗi định dạng được sử dụng lại thường xuyên khi cần thiết để đáp ứng các đối số."


%Phương thức duy nhất hoạt động cho dấu gạch chéo đơn được đề cập trong nhiệm vụ. Để phục vụ khi có nhiều dấu gạch chéo, ${parts[@]%%/*}công trình. Đây là một liên kết đến một chút thông tin về vấn đề gạch chéo: Dấu gạch chéo kép có ý nghĩa gì trong đường dẫn UNIX? Là 'cd dir / subir // hợp lệ ...
Peter.O

2
@fered: /*trong trường hợp này không có nghĩa là không hoặc nhiều dấu gạch chéo , mà là một dấu gạch chéo theo sau bởi bất kỳ số lượng ký tự. Điều đó có nghĩa là nếu đường dẫn của bạn bắt đầu bằng dấu gạch chéo, kết quả sẽ là chuỗi rỗng!
l0b0

Tôi đã xem xét, theo ví dụ, sẽ chỉ có dấu gạch chéo. Tuy nhiên, để thích ứng với khả năng của một dấu gạch chéo hàng đầu, bash's extglob(với regex) có thể được sử dụng .. shopt -s extglob; ${parts[@]%%/+(/)}...
Peter.O

15

Câu trả lời đơn giản là ngừng lo lắng và yêu nhiều nhát chém. Nhiều dấu gạch chéo có tác dụng tương tự như một dấu gạch chéo (ngoại trừ một đường dẫn bắt đầu //có ý nghĩa khác nhau trên một vài hệ thống; các lớp mô phỏng unix trên Windows là những lớp duy nhất tôi có thể đặt tên). Đó là theo thiết kế, và có thể lắp ráp tên tệp mà không phải lo lắng về nhiều dấu gạch chéo là một phần chính của quyết định thiết kế đó.

Để tham gia các phần tử mảng, trong zsh, bạn có thể sử dụng j cờ mở rộng tham số .

dir=${(j:/:)FOLDERS}

Bạn có thể squash các dấu gạch chéo trùng lặp trong khi bạn đang ở đó, nhưng đó hoàn toàn là mỹ phẩm.

setopt extended_glob
dir=${${(j:/:)FOLDERS}//\/\/##/\/}

Trong ksh và bash, bạn có thể tham gia một mảng bằng ký tự đầu tiên $IFSlà dấu phân cách. Sau đó, bạn có thể squish các dấu gạch chéo trùng lặp. Trong bash, bạn sẽ cần phải làm shopt -s extglobđể kích hoạt các chuỗi ksh trong dòng cuối cùng của đoạn trích dưới đây.

IFS=/
dir="${FOLDERS[*]}"
unset IFS
dir=${dir//\/+(\/)//}

3

Làm thế nào là sedkhông làm việc cho bạn? Hãy thử sed 's|/\+|/|g'sau khi nối, hoặc sed 's|/||g'trước.


1

bash 4giới thiệu toàn cầu mở rộng, cho phép khớp biểu thức chính quy trong thay thế tham số ${var....}... Nó bị tắt theo mặc định. Để kích hoạt nó cho tập lệnh của bạn, chỉ cần đặt tùy chọn shell extglob ...

Giả sử $ dir ==/home/me/////////stuff//items

shopt -s extglob; dir="${dir//+(\/)//}"

Giá trị kết quả của $ dir

/home/me/stuff/items  

Dưới đây là một số ví dụ với do-s và-đừng-s - Bash Extended Globbing

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.