mengubah IFS sementara sebelum for loop [duplikat]

Aug 16 2020

Saya tahu bahwa SHELLmemungkinkan penugasan variabel dilakukan segera sebelum perintah, seperti itu IFS=":" read a b c d <<< "$here_string"berfungsi ...

Apa yang saya ingin tahu adalah apakah tugas seperti itu tidak berfungsi saat dilakukan dengan pernyataan gabungan seperti loop? Saya mencoba sesuatu seperti IFS=":" for i in $PATH; do echo $i; doneitu tetapi menghasilkan kesalahan sintaksis. Saya selalu dapat melakukan sesuatu seperti itu oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS", tetapi saya ingin tahu apakah ada cara untuk membuat tugas sebaris seperti itu berfungsi untuk pernyataan majemuk seperti forloop?

Jawaban

3 Quasímodo Aug 16 2020 at 21:12

foradalah kata khusus dan dengan demikian mengikuti aturan khusus :

Kata-kata berikut akan dikenali sebagai kata-kata yang dipesan:

! {} kasus dilakukan elif lain esac fi untuk jika kemudian sampai saat

Pengenalan ini hanya akan terjadi jika tidak ada karakter yang dikutip dan saat kata tersebut digunakan sebagai:

  • Kata pertama dari sebuah perintah

  • Kata pertama setelah salah satu kata yang dicadangkan selain case , for , atau in

  • Kata ketiga dalam perintah kasus (hanya dalam valid dalam kasus ini)

  • Kata ketiga dalam perintah for (hanya dalam dan lakukan yang valid dalam kasus ini)

Jika kamu mencoba

IFS=":" for i in $PATH; do echo $i; done

, dengan aturan di atas, itu bukan forperulangan, karena kata kunci bukan kata pertama dari perintah. Tapi niat Anda bisa tercapai dengan

IFS=: printf '%s\n' $PATH

$PATHmengalami pemisahan kata :seperti yang diharapkan dan setiap kata yang dihasilkan dicetak oleh printf, diikuti oleh baris baru.


Anda mungkin sudah familiar dengan pendekatan yang valid ini:

while IFS= read -r line; do

whileadalah kata pertama dari perintah, dan IFSpenugasan diterapkan read, jadi semuanya OK.