Di bash saya memiliki array dengan nama jalur, dan saya ingin mengganti masing-masing dengan yang berbeda menggunakan sed, seperti:

sed 's@^(.*?)master_repo(.*?)@\1"${SOME_REPO_NAME}"\2@g' <<< ${FULL_TGT_DIRS[${i}]}

Contoh nama jalur yang merupakan elemen array adalah:

/Volumes/munki/master_repo/pkgs/apps

Saya ingin mengganti nama jalur "master_repo" dengan misalnya "somedir", yang disimpan di $SOME_REPO_NAME, jadi saya mendapatkan:

/Volumes/munki/somedir/pkgs/apps

Atau dengan substitusi string bawaan:

for i in ${FULL_TGT_DIRS[@]}
do
    FULL_TGT_DIRS[$i]=${FULL_TGT_DIRS[$i]/master_repo/$SOME_REPO_NAME}
    #sed 's@^(.*?)master_repo(.*?)@\1"${SOME_REPO_NAME}"\2@g' <<< ${FULL_TGT_DIRS[${i}]}
done

Saya selalu mendapatkan kesalahan berikut saat menjalankan skrip saya:

> /usr/local/bin/repomgr: line 135:
> /Volumes/munki/master_repo/pkgs/apps: syntax error: operand expected
> (error token is "/Volumes/munki/master_repo/pkgs/apps")

Saya telah mencoba menggunakan pemisah dan opsi sed yang berbeda, serta mengacak-acak konstelasi kutipan yang berbeda. Saya tidak menulis skrip bash setiap hari jadi mungkin saya melewatkan sesuatu?

BTW, saya menjalankan ini di Mac dan karena itu hanya memiliki bash 3.2 yang saya miliki.

2
pming 18 Maret 2017, 01:23

2 jawaban

Jawaban Terbaik

Tidak perlu menggunakan sed untuk ini, bash memiliki pengganti string bawaan dalam perluasan parameternya.

var=/Volumes/munki/master_repo/pkgs/apps
$SOME_REPO_NAME=somedir
newvar=${var/master_repo/$SOME_REPO_NAME}

Dalam loop for-in, variabel disetel ke elemen array, bukan indeks array, jadi Anda tidak boleh menggunakan FULL_TGT_DIRS[$i] -- $i berisi nama path. Jadi loopnya harus:

for file in ${FULL_TGT_DIRS[@]}
do
    file=${file/master_repo/$SOME_REPO_NAME}
    # Do something with $file here
done

Jika Anda perlu memodifikasi array di tempatnya, Anda memerlukan loop yang berbeda untuk indeks:

for ((i = 0; i < ${#FULL_TGT_DIRS[@]}; i++))
do
    FULL_TGT_DIRS[$i]=${FULL_TGT_DIRS[$i]/master_repo/"$SOME_REPO_NAME"}
done
0
Barmar 17 Maret 2017, 23:49

Anda bahkan dapat melangkah lebih jauh menggunakan pengganti bashes sendiri:

for file in "${FULL_TGT_DIRS[@]/master_repo/somedir}"
do
  ...work on file variable here...
done
0
grail 18 Maret 2017, 09:03