Thay thế Bash bằng biến được định nghĩa từ một mẫu toàn cầu


10

Ví dụ dưới đây giải thích vấn đề. Tại sao được FILENAMEin chính xác khi lặp lại và được coi là một mẫu khi sử dụng thay thế?

#!/bin/bash

FILEPATH_WITH_GLOB="/home/user/file_*"
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
echo $FILENAME                #file_1234
echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

Câu trả lời:


15
FILEPATH_WITH_GLOB="/home/user/file_*"

Bây giờ, FILEPATH_WITH_GLOBchứa/home/user/file_*

FILENAME=$(basename "$FILEPATH_WITH_GLOB")

FILENAMEchứa file_*.

echo $FILENAME                #file_1234

$FILENAMEkhông được trích dẫn trong ngữ cảnh danh sách, việc mở rộng đó trải qua toán tử split + global, do đó, nó được mở rộng thành danh sách tệp phù hợp: việc tạo tên tệp được thực hiện khi mở rộng tham số .

echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

Nó vẫn là một mở rộng tham số không được trích dẫn trong ngữ cảnh danh sách, vì vậy vẫn trải qua quá trình phân tách + toàn cầu. Tuy nhiên, ở đây, ile_*mẫu không khớp với bất kỳ tệp nào, vì vậy nó sẽ mở rộng sang chính nó.

Những gì bạn có thể muốn ở đây là:

shopt -s nullglob # have globs expand to nothing when they don't match
set -- /home/user/file_* # expand that pattern into the list of matching 
                         # files in $1, $2...
for file do  # loop over them
  filename=$(basename -- "$file")
  printf '%s\n' "$filename" "${filename:1:5}"
done

Hoặc bạn có thể lưu trữ chúng trong một mảng:

shopt -s nullglob
files=(/home/user/file_*)

Nếu bạn chỉ quan tâm đến trận đấu đầu tiên hoặc bạn biết chỉ có một trận đấu, thì bạn có thể tham khảo tệp đó là $files. bashcó hành vi gây phiền nhiễu thường $filesmở rộng ra ${files[0]}thay vì tất cả các yếu tố của mảng (một hành vi được kế thừa từ ksh, cố định zsh), nhưng ở đây, đó sẽ là hành vi mong muốn một lần.


Cảm ơn đã giải thích. Quản lý để làm một cách giải quyết với FILEPATH_WITH_GLOB=`echo /home/user/file_*` sau lời giải thích của bạn.
TheMeaningfulEngineer

@Alan, đó là cách sai để giải quyết nó. Bạn muốn sử dụng một mảng ở đây. Các tham số vị trí như trong ví dụ của tôi ($ 1, $ 2 ...) hoặc một bashmảng như : files=(/home/user/file_*).
Stéphane Chazelas

(và tất cả các biến chữ hoa nên thực sự được dành riêng cho các biến môi trường, echokhông nên được sử dụng cho dữ liệu tùy ý , các biến không được bỏ qua trong ngữ cảnh danh sách).
Stéphane Chazelas
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.