Saya telah menemukan skrip ini:
#! /bin/bash
if (( $# < 3 )); then
echo "$0 old_string new_string file [file...]"
exit 0
else
ostr="$1"; shift
nstr="$1"; shift
fi
echo "Replacing \"$ostr\" with \"$nstr\""
for file in $@; do
if [ -f $file ]; then
echo "Working with: $file"
eval "sed 's/"$ostr"/"$nstr"/g' $file" > $file.tmp
mv $file.tmp $file
fi
done
Apa arti garis yang digunakan shift
? Saya kira skrip harus digunakan dengan setidaknya argumen jadi ...?
shell-script
arguments
Patryk
sumber
sumber
pushd
danpopd
).bash
, pertanyaannya adalah umum untuk semua shell, oleh karena itu standar Posix menang: pubs.opengroup.org/onlinepubs/9699919799/utilities/…Seperti yang dijelaskan oleh komentar goldilocks dan referensi kemanusiaan,
shift
tetapkan kembali parameter posisi ($1
,,$2
dll.) Sehingga$1
mengambil nilai lama$2
,$2
mengambil nilai$3
, dll. * Nilai lama$1
dibuang. ($0
tidak diubah.) Beberapa alasan untuk melakukan ini termasuk:$10
tidak berfungsi - ini diartikan sebagai$1
digabungkan dengan0
(dan mungkin menghasilkan sesuatu sepertiHello0
). Setelah ashift
, argumen kesepuluh menjadi$9
. (Namun, di sebagian besar shell modern, Anda dapat menggunakan${10}
.)for
jauh lebih baik untuk itu.$1
dan$2
merupakan string teks, sementara$3
dan semua parameter lainnya adalah nama file.Jadi begini caranya. Misalkan skrip Anda dipanggil
Patryk_script
dan disebut sebagaiScript melihat
Pernyataan
ostr="$1"
mengatur variabelostr
menjadiUSSR
.shift
Pernyataan pertama mengubah parameter posisi sebagai berikut:Pernyataan
nstr="$1"
mengatur variabelnstr
menjadiRussia
.shift
Pernyataan kedua mengubah parameter posisi sebagai berikut:Dan kemudian
for
perubahan lingkaranUSSR
($ostr
) keRussia
($nstr
) dalam fileTreaty1
,Atlas2
danPravda3
.Ada beberapa masalah dengan skrip.
Jika skrip dipanggil sebagai
ia melihat
namun, karena
$@
tidak dikutip, ruang diWorld Atlas2
tidak dikutip, danfor
lingkaran berpikir itu memiliki empat file:Treaty1
,World
,Atlas2
, danPravda3
. Ini juga harus(Mengutip karakter khusus dalam argumen) atau secara sederhana
(yang setara dengan versi yang lebih panjang).
Ini tidak perlu menjadi
eval
, dan meneruskan input pengguna yang tidak dicentang keeval
bisa berbahaya. Misalnya, jika skrip dipanggil sebagaiitu akan mengeksekusi
rm *
! Ini adalah masalah besar jika skrip dapat dijalankan dengan hak istimewa lebih tinggi dari pada pengguna yang memintanya; misalnya, jika dapat dijalankan melaluisudo
atau dipanggil dari antarmuka web. Ini mungkin tidak begitu penting jika Anda hanya menggunakannya sebagai diri sendiri, di direktori Anda. Tapi itu bisa diubah menjadiIni masih memiliki beberapa risiko, tetapi mereka jauh lebih ringan.
if [ -f $file ]
,> $file.tmp
danmv $file.tmp $file
harusif [ -f "$file" ]
,> "$file.tmp"
danmv "$file.tmp" "$file"
, masing-masing, untuk menangani nama file yang mungkin memiliki spasi (atau karakter lucu lainnya) di dalamnya. (eval "sed …
Perintah juga mangles nama file yang memiliki spasi di dalamnya.)*
shift
mengambil argumen opsional: bilangan bulat positif yang menentukan berapa banyak parameter yang bergeser. Standarnya adalah satu (1
). Misalnya,shift 4
menyebabkan$5
menjadi$1
,$6
menjadi$2
, dan seterusnya. (Perhatikan bahwa contoh dalam Bash Guide for Beginners salah.) Dan skrip Anda dapat dimodifikasi untuk mengatakanyang mungkin dianggap lebih jelas.
Catatan Akhir / Peringatan:
Bahasa Windows Command Prompt (file batch) juga mendukung
SHIFT
perintah, yang pada dasarnya melakukan hal yang sama denganshift
perintah di shell Unix, dengan satu perbedaan mencolok, yang akan saya sembunyikan untuk mencegah orang-orang menjadi bingung olehnya:sumber
shift
dapat diterapkan kewhile
,,until
dan bahkanfor
loop untuk menangani array dengan cara yang jauh lebih halus daripadafor
loop sederhana . Saya sering menemukan itu berguna dalamfor
loop seperti ...set -f -- $args; IFS=$split; for arg do set -- $arg; shift "${number_of_fields_to_discard}" && fn_that_wants_split_arg "$arg"; done
Penjelasan paling sederhana adalah ini. Pertimbangkan perintahnya:
Tanpa bantuan
shift
Anda, Anda tidak dapat mengekstraksi nilai lengkap lokasi karena nilai ini bisa panjang secara sewenang-wenang. Ketika Anda menggeser dua kali, argumenSET
danlocation
dihapus sedemikian rupa sehingga:Menatap hal itu sangat lama
$@
. Itu berarti, itu dapat menyimpan lokasi lengkap ke dalam variabelx
terlepas dari spasi dan koma yang dimilikinya. Jadi dalam ringkasan, kita panggilshift
dan kemudian kita mengambil nilai dari apa yang tersisa dari variabel$@
.PEMBARUAN Saya menambahkan di bawah ini cuplikan yang sangat singkat yang menunjukkan konsep dan kegunaan
shift
tanpanya, akan sangat, sangat sulit untuk mengekstrak bidang dengan benar.Penjelasan : Setelah itu
shift
, variabel b harus berisi sisa barang-barang yang diteruskan, tidak peduli ruang atau lainnya. Ini[ -n "$b" ] && echo $b
adalah perlindungan sehingga kami hanya mencetak b jika memiliki konten.sumber
"$*"
alih-alih"$@"
. (3) Saya akan mengubah jawaban Anda, tetapi saya tidak melakukannya, karena Anda mengatakan "bergeser dua kali" tetapi Anda tidak benar-benar menunjukkannya dalam kode. (4) Jika Anda ingin skrip dapat mengambil nilai multi-kata dari baris perintah, mungkin lebih baik meminta pengguna untuk memasukkan seluruh nilai ke dalam tanda kutip. … (Lanjutan)Philippines 6014
), ruang utama, spasi tambahan, atau tab. (5) BTW, Anda mungkin juga dapat melakukan apa yang Anda lakukan di sini dengan bashx="${*:3}"
.shift
perintah. Anda mungkin merujuk ke perbedaan halus $ @ versus $ *. Tetapi kenyataannya masih tetap, bahwa cuplikan saya di atas dapat secara akurat mengekstraksi lokasi tidak peduli berapa banyak ruang yang telah diikutinya atau di depannya tidak masalah. Setelah shift, lokasi akan berisi lokasi yang benar.shift
memperlakukan argumen baris perintah sebagai antrian FIFO, itu elemen popleft setiap kali itu dipanggil.sumber