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:
IFSsingkatan 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 IFSterdiri 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 mystringmenjadi kata-kata juga - tetapi sekarang, itu hanya memperlakukan titik dua sebagai batas kata.
Karakter pertama IFSadalah 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 IFSmemasukkan 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 cdan d).
IFS=:itu akan dibagi menjadi empat bidang: "a", "b", ""(string kosong) dan " c d "(sekali lagi, dua ruang antara cdan 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 ksh93sintaks juga didukung oleh bash, zsh, mkshdan 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.
\nadalah urutan pelarian untuk baris baru, sehingga IFSakhirnya ditetapkan ke karakter baris baru.
bashpanduan 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 IFSmembuat shell berperilaku sangat berbeda IFS=. Juga byte pertama di IFS juga istimewa "${named_array[*]}"- tetapi tidak masalah ketika ekspansi tidak
$IFSadalah salah satu dari dua hal utama yang dilakukan saat memperluas variabel yang tidak dikutip dalam konteks daftar (ini adalah splitbagian dari split+globoperator). Yang lainnya adalah globbing. Saat menggunakan pemisahan pekerjaan, Anda biasanya perlu mengeluarkan set -funtuk menonaktifkan globbagian.
$IFSjuga digunakan oleh readperintah builtin
Di dalam kutipan tunggal boneka, beberapa karakter dievaluasi secara khusus. Misalnya, \nditerjemahkan 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 bashdikatakan, itu
digunakan untuk pemisahan kata setelah ekspansi dan untuk memecah baris menjadi kata-kata dengan
readperintah builtin. Nilai standarnya adalah<space><tab><newline>.
dollared single quotesyang berbeda dari kutipan tunggal sederhana.
Singkatnya, IFS=$'\n'tetapkan baris baru \nke 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 $IFSmelalui 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.pdfatau 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