Di awal skrip bash shell adalah baris berikut:
IFS=$'\n'
Apa arti di balik koleksi simbol ini?
IFS=$'\n'
adalah bashism (+ cangkang lainnya, gunakan ANSI-C Quoting , untuk penyelesaian masalah, lihat stackoverflow.com/questions/10748703/…
Di awal skrip bash shell adalah baris berikut:
IFS=$'\n'
Apa arti di balik koleksi simbol ini?
IFS=$'\n'
adalah bashism (+ cangkang lainnya, gunakan ANSI-C Quoting , untuk penyelesaian masalah, lihat stackoverflow.com/questions/10748703/…
Jawaban:
IFS
singkatan dari "pemisah bidang internal". Ini digunakan oleh shell untuk menentukan bagaimana melakukan pemisahan kata, yaitu bagaimana mengenali batasan kata.
Coba ini di shell seperti bash (shell lain mungkin menangani ini secara berbeda, misalnya zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
Nilai default untuk IFS
terdiri dari karakter spasi putih (tepatnya: spasi, tab, dan baris baru). Setiap karakter dapat menjadi batas kata. Jadi, dengan nilai default IFS
, loop di atas akan mencetak:
Word: foo:bar
Word: baz
Word: rab
Dengan kata lain, shell berpikir bahwa spasi putih adalah batas kata.
Sekarang, coba pengaturan IFS=:
sebelum menjalankan loop. Kali ini, hasilnya adalah:
Word: foo
Word: bar baz rab
Sekarang, shell terbagi mystring
menjadi kata-kata juga - tetapi sekarang, itu hanya memperlakukan titik dua sebagai batas kata.
Karakter pertama IFS
adalah spesial: Digunakan untuk membatasi kata-kata dalam output saat menggunakan $*
variabel khusus (contoh diambil dari Advanced Bash Scripting Guide , di mana Anda juga dapat menemukan informasi lebih lanjut tentang variabel-variabel khusus seperti itu):
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
Dibandingkan dengan:
$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z
Perhatikan bahwa dalam kedua contoh, shell masih akan memperlakukan semua karakter :
, -
dan ;
sebagai batas kata. Satu-satunya hal yang berubah adalah perilaku $*
.
Hal penting lain yang perlu diketahui adalah bagaimana apa yang disebut "ruang putih IFS" diperlakukan . Pada dasarnya, segera setelah IFS
memasukkan karakter spasi putih, spasi spasi awal dan jejak dilucuti dari string untuk dipisah sebelum memprosesnya dan urutan karakter spasi putih berturut-turut juga membatasi bidang. Namun, ini hanya berlaku untuk karakter spasi putih yang sebenarnya ada di IFS
.
Sebagai contoh, mari kita lihat string "a:b:: c d "
(spasi spasi dan dua karakter spasi antara c
dan d
).
IFS=:
itu akan dibagi menjadi empat bidang: "a"
, "b"
, ""
(string kosong) dan " c d "
(sekali lagi, dua ruang antara c
dan d
). Perhatikan spasi putih terkemuka dan tertinggal di bidang terakhir.IFS=' :'
, itu akan dibagi menjadi lima bidang: "a"
, "b"
, ""
(string kosong), "c"
dan "d"
. Tidak ada spasi putih terkemuka dan tertinggal di mana pun.Perhatikan bagaimana beberapa, karakter spasi putih berturut-turut membatasi dua bidang pada contoh kedua, sedangkan banyak, karakter titik dua berturut-turut tidak (karena mereka bukan karakter spasi putih).
Adapun IFS=$'\n'
, yang merupakan ksh93
sintaks juga didukung oleh bash
, zsh
, mksh
dan FreeBSD sh
(dengan variasi antara semua kerang). Mengutip manual bash:
Kata-kata dalam bentuk $ 'string' diperlakukan secara khusus. Kata diperluas ke "string", dengan karakter backslash-escape diganti seperti yang ditentukan oleh standar ANSI C.
\n
adalah urutan pelarian untuk baris baru, sehingga IFS
akhirnya ditetapkan ke karakter baris baru.
bash
panduan penulisan skrip, atau apa pun. Pada intinya, informasi yang tersedia di tautan seperti itu kurang penting. Lagi pula, dengan demikian melewatkan dua poin penting tentang shell splitting - globbing dan IFS whitespace.
unset IFS
membuat shell berperilaku sangat berbeda IFS=
. Juga byte pertama di IFS juga istimewa "${named_array[*]}"
- tetapi tidak masalah ketika ekspansi tidak
$IFS
adalah salah satu dari dua hal utama yang dilakukan saat memperluas variabel yang tidak dikutip dalam konteks daftar (ini adalah split
bagian dari split+glob
operator). Yang lainnya adalah globbing. Saat menggunakan pemisahan pekerjaan, Anda biasanya perlu mengeluarkan set -f
untuk menonaktifkan glob
bagian.
$IFS
juga digunakan oleh read
perintah builtin
Di dalam kutipan tunggal boneka, beberapa karakter dievaluasi secara khusus. Misalnya, \n
diterjemahkan ke baris baru.
Jadi, baris khusus ini memberikan baris baru ke variabel IFS. IFS, pada gilirannya, adalah variabel khusus di bash: Pemisah Bidang Internal. Seperti yang man bash
dikatakan, itu
digunakan untuk pemisahan kata setelah ekspansi dan untuk memecah baris menjadi kata-kata dengan
read
perintah builtin. Nilai standarnya adalah<space><tab><newline>
.
dollared single quotes
yang berbeda dari kutipan tunggal sederhana.
Singkatnya, IFS=$'\n'
tetapkan baris baru \n
ke variabel IFS
.
$'string'
construct adalah mekanisme penawaran yang digunakan untuk mendekode ANSI C seperti escape sequence. Sintaks ini berasal dari ksh93
, dan portabel untuk shell modern seperti bash
, zsh
, pdksh
, busybox sh
.
Sintaks ini tidak didefinisikan oleh POSIX, tetapi diterima untuk SUS edisi 7 .
Saya lebih suka menjelaskan $IFS
melalui contoh:
Jika Anda ingin cp atau mv atau pemrosesan file lain, IFS kosong oleh defualt, Ketika file Anda memiliki meta char atau ruang seperti:
Linux Administration.pdf
atau Free Software Fundation.ogg
, Tentu Anda akan memiliki masalah, Karena: Linux mempertimbangkan terpisah param dan Administartion mempertimbangkan param terpisah. Jadi bash memiliki built-in variable
, Kemudian Anda dapat menginisialisasi IFS==$(echo -en "\n\b")
, Kemudian bash membuang meta char dan spasi di antara nama file, Misalnya:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS