Câu hỏi Làm cách nào để nối các chuỗi từ danh sách trong tập lệnh bash?


Ví dụ:

List="A B C D"
for I in $List
do
    OUT=$OUT" -$I"
done

Khi tôi chạy kết quả này là:

" -A -B -C -D"

nhưng muốn nó là:

"-A -B -C -D"

Làm thế nào để tôi nối mà không có không gian hàng đầu?

Btw này là một danh sách đối số cho một tập lệnh.


4
2017-09-17 11:57


gốc




Các câu trả lời:


Sử dụng mở rộng tham số có điều kiện:

List="A B C D"
for I in $List
do
    OUT=${OUT:+$OUT }-$I
done

Cách diễn đạt ${OUT:+$OUT } mở rộng thành không có gì nếu OUT không được đặt hoặc trống; nếu nó được thiết lập để một cái gì đó, sau đó nó mở rộng đến cái gì đó theo sau là một không gian.

Tuy nhiên, loại hoạt động này - xử lý một chuỗi được phân cách bằng khoảng trống được liệt kê - đầy những vấn đề có thể xảy ra: trích dẫn, các giá trị tự nhiên chứa khoảng trắng, v.v. Bạn nên sử dụng mảng:

List=(A B C D)
for I in "${List[@]}"
do    
    OUT=${OUT:+$OUT }-$I
done

Tùy thuộc vào những gì bạn đang làm với $OUT, nó có thể có ý nghĩa để làm cho nó một mảng là tốt:

List=(A B C D)
OUT=()
for I in "${List[@]}"; do
  OUT+=("-$I")
done

Sau đó, bạn sẽ sử dụng "${OUT[@]}" để truyền các phần tử của mảng tới một lệnh khác dưới dạng các đối số riêng biệt.

Để quay lại phiên bản gốc của bạn, trong trường hợp cụ thể này, bạn cũng có thể sử dụng sed và bỏ qua toàn bộ vòng lặp bash:

OUT=$(sed -E 's/^| /&-/g' <<<"$List")

9
2017-09-17 12:13





Bạn có thể loại bỏ không gian hàng đầu bằng cách sử dụng lệnh sau vòng lặp for, chẳng hạn như

OUT=${OUT# }

Dẫn tới

List="A B C D"
for I in $List
do
    OUT=$OUT" -$I"
done
OUT=${OUT# }

0
2017-09-17 12:11