Apa itu 'IFS'?

Jawaban:

17

IFSsingkatan - itu adalah karakter yang memisahkan bidang. Dalam contoh yang Anda poskan, ini disetel ke karakter baris baru ( ); jadi setelah Anda mengaturnya, akan memproses teks baris demi baris. Dalam contoh itu, Anda bisa mengubah nilai (ke beberapa huruf yang Anda miliki di file input) dan memeriksa bagaimana teks akan dibagi.Input Internal Field Separator\nforIFS

BTW, dari jawaban yang Anda posting solusi kedua adalah yang direkomendasikan ...

Seperti @jasonwryan perhatikan, itu bukan Inputtapi Internal. Nama Inputberasal dari awkmana ada juga OFS- Output Field Separator.

pbm
sumber
1
Perhatikan bahwa IFS juga digunakan untuk menggabungkan parameter untuk output. Dari halaman bash man: "Ketika ekspansi terjadi dalam tanda kutip ganda, itu berkembang menjadi satu kata dengan nilai setiap parameter dipisahkan oleh karakter pertama dari variabel khusus IFS."
Eric
Satu juga harus mencatat bahwa sementara Sadalah untuk pemisah di kulit Bourne dari mana asalnya. Dalam shell Korn dan sebagian besar shell Bourne-seperti yang sekarang telah ditentukan oleh POSIX, Sadalah untuk Pembatas (hanya meregangkan imajinasi Anda sedikit) seperti A::B:misalnya dibagi menjadi "A", "" dan "B" (tidak ada tambahan ""). Itu berbeda dari awk's FSatau sbendera perluasan parameter zsh.
Stéphane Chazelas
27

IFStidak terkait langsung dengan perulangan, ini terkait dengan pemisahan kata. IFSsecara tidak langsung menentukan bagaimana output dari perintah dipecah menjadi beberapa bagian yang berulang-ulang berulang.

Ketika Anda memiliki substitusi variabel $fooatau substitusi perintah yang tidak dilindungi $(foo), ada dua kasus:

  • Jika konteksnya mengharapkan satu kata, misalnya ketika substitusi adalah antara tanda kutip ganda "$foo", atau dalam penugasan variabel x=$foo, maka string yang dihasilkan dari substitusi tersebut digunakan apa adanya.
  • Jika konteksnya mengharapkan banyak kata, yang merupakan kasus sebagian besar waktu, maka dua ekspansi lebih lanjut dilakukan pada string yang dihasilkan:
    • Tali dipisah menjadi kata-kata . Setiap karakter yang muncul $IFSdianggap sebagai pemisah kata. Misalnya IFS=":"; foo="12:34::78"; echo $foomencetak 12 34 ​ 78(dengan dua spasi di antara 34dan 78, karena ada kata kosong).
    • Setiap kata diperlakukan sebagai pola gumpalan dan diperluas menjadi daftar nama file . Misalnya, foo="*"; echo $foomencetak daftar file di direktori saat ini.

Untuk loop, seperti banyak konteks lainnya, mengharapkan daftar kata-kata. Begitu

for x in $(foo); do 

memecah $(foo)menjadi kata-kata, dan memperlakukan setiap kata sebagai pola gumpalan. Nilai default IFSadalah spasi, tab dan baris baru , jadi jika foomencetak dua baris hello worlddan howdykemudian loop body dieksekusi dengan x=hello, maka x=worlddan x=howdy. Jika IFSsecara eksplisit diubah hanya berisi baris baru, maka loop dijalankan untuk hello worlddan howdy. Jika IFSdiubah menjadi o, maka loop dijalankan untuk hell, ​ w, rld​␤h(di mana ​␤adalah karakter baris baru) dan wdy.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Mengapa Anda menyebut "Tidak Langsung" dalam "IFS indirectly determines how ..."?
αғsнιη
1
@ αғsнιη IFS(langsung) menentukan bagaimana output dari substitusi perintah dipecah, yang kemudian (secara tidak langsung) menentukan apa loop berulang.
Gilles 'SANGAT berhenti menjadi jahat'
5

Dari man bash

IFS Pemisah Bidang Internal yang digunakan untuk pemisahan kata setelah ekspansi dan untuk memecah baris menjadi kata-kata dengan perintah baca bawaan. Nilai standarnya adalah "<spasi> <tab> <newline>".

Ini adalah salah satu variabel internal Bash. Ini menentukan bagaimana Bash mengenali bidang, atau batas kata, ketika itu menerjemahkan string karakter.

Meskipun default ke spasi putih (spasi, tab, dan baris baru), mungkin diubah, misalnya, untuk mem-parsing file data yang dipisahkan koma.

http://tldp.org/LDP/abs/html/internalvariables.html

jasonwryan
sumber
0

Selain jawaban hebat sebelumnya, izinkan saya menambahkan bahwa IFS sangat berguna untuk penguraian portabel dan efisien dalam kasus-kasus sederhana dalam kombinasi dengan set . Efisien, karena menghindari penggunaan subkulit dan alat pemijahan seperti grep atau sed:

resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
    xxIFS=$IFS
    IFS='x'
    set -- $res
    width=$1
    height=$2
    # handle width and height
    IFS=$xxIFS
done;
IFS=$xIFS

Harap perhatikan bahwa kita perlu menyimpan dan memulihkan nilai IFS sebelumnya untuk menghindari kerusakan yang tidak diinginkan di bagian skrip lain.

pmod
sumber