Substitusi Bash dengan variabel yang ditentukan dari pola glob


10

Contoh di bawah ini menjelaskan masalah ini. Mengapa FILENAMEdicetak dengan benar ketika digemakan dan dianggap sebagai pola saat menggunakan substitusi?

#!/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

Jawaban:


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

Sekarang, FILEPATH_WITH_GLOBberisi/home/user/file_*

FILENAME=$(basename "$FILEPATH_WITH_GLOB")

FILENAMEberisi file_*.

echo $FILENAME                #file_1234

$FILENAMEtidak dikutip dalam konteks daftar, bahwa ekspansi mengalami split + glob operator, jadi itu diperluas ke daftar file yang cocok: pembuatan nama file dilakukan pada ekspansi parameter .

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

Ini masih merupakan perluasan parameter yang tidak dikutip dalam konteks daftar, jadi masih mengalami split + glob. Namun di sini, ile_*polanya tidak cocok dengan file apa pun, jadi pola itu berkembang sendiri.

Apa yang mungkin Anda inginkan di sini adalah:

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

Atau Anda dapat menyimpannya dalam sebuah array:

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

Jika Anda hanya peduli pada pertandingan pertama, atau Anda tahu hanya ada satu pertandingan, Anda dapat merujuk ke file tersebut sebagai $files. bashmemiliki perilaku yang biasanya menjengkelkan yang $filesmeluas ke ${files[0]}semua elemen array (perilaku yang diwarisi dari ksh, diperbaiki zsh), tetapi di sini, itu akan menjadi perilaku yang diinginkan untuk sekali.


Terima kasih untuk penjelasannya. Berhasil melakukan penyelesaian FILEPATH_WITH_GLOB=`echo /home/user/file_*` setelah penjelasan Anda.
— TheMeaningfulEngineer

@Lan, itu cara yang salah untuk mengatasinya. Anda ingin menggunakan array di sini. Entah parameter posisi seperti dalam contoh saya ($ 1, $ 2 ...) atau basharray seperti: files=(/home/user/file_*).
— Stéphane Chazelas

(dan semua variabel huruf besar harus benar-benar dicadangkan untuk variabel lingkungan, echotidak boleh digunakan untuk data arbitrer , variabel tidak boleh ditinggalkan tanda kutip dalam konteks daftar).
— Stéphane Chazelas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.