bir for döngüsünden önce geçici olarak IFS'yi değiştirme [yineleme]

Aug 16 2020

SHELLDeğişken atamanın bir komuttan hemen önce gerçekleşmesine izin verdiğini biliyorum , öyle ki IFS=":" read a b c d <<< "$here_string"işe yarıyor ...

Merak ettiğim şey, bu tür atamaların döngüler gibi bileşik ifadelerle yapıldığında çalışmıyor mu? Benzeri bir şey denedim IFS=":" for i in $PATH; do echo $i; doneama bu bir sözdizimi hatasıyla sonuçlanıyor. Her zaman böyle bir şey yapabilirdim oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS", ancak bu tür satır içi atamaları fordöngüler gibi bileşik ifadeler için çalıştırmanın bir yolu olup olmadığını bilmek istedim.

Yanıtlar

3 Quasímodo Aug 16 2020 at 21:12

forayrılmış bir kelimedir ve bu nedenle özel kuralları izler :

Aşağıdaki kelimeler ayrılmış kelimeler olarak kabul edilecektir:

! {} case do done elif else esac fi for if in if in it in then than that

Bu tanıma, yalnızca karakterlerden hiçbiri alıntılanmadığında ve kelime şu şekilde kullanıldığında gerçekleşir:

  • Bir komutun ilk kelimesi

  • Case , for veya in dışındaki ayrılmış sözcüklerden birini izleyen ilk kelime

  • Bir durum komutundaki üçüncü kelime ( bu durumda yalnızca içinde geçerlidir)

  • For komutundaki üçüncü kelime ( bu durumda yalnızca içinde ve do geçerlidir)

Eğer denersen

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

Yukarıdaki kurallara göre, foranahtar kelime komutun ilk kelimesi olmadığından bu bir döngü değildir. Ama amacına ulaşabilirsin

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

$PATH:beklendiği gibi sözcük bölünmesine maruz kalır ve ortaya çıkan her sözcük printf, ardından bir satırsonu ile basılır .


Bu geçerli yaklaşıma aşina olabilirsiniz:

while IFS= read -r line; do

whilekomutun ilk kelimesi ve IFSatama için geçerli olduğu için readher şey yolunda.