'IFS = $' \ n 'içindeki' \ n 'bir değişken midir?


12

Newline'ı IFSbir önek olarak $ ile ayarlamanız gerektiğini fark ettim

IFS=$'\n'

ama iki nokta üst üste koyulursa,

IFS=:

\nbir değişkendir?

Yanıtlar:


21

Yani $'...'içinde bashgenişleme parametre değil, getirdiği alıntı özel bir tür var ksh93olanlar genişler \n, \x0a, \12bir yeni satır karakteri kodlar. zshAyrıca eklendi \u000a. ksh93ve bashayrıca sahip \cjiken zshsahiptir \C-J. ksh93gibi varyasyonları da destekler \x{a}.

Bu $bir biçim veya genişleme olduğuna dair bir ipucudur. Ama her durumda, bu açılımları diğer formlarından farklı olduğunu kullanımı $(gibi $((1 + 1)), $paramya $(cmd)da (burada çift tırnak veya belgeler içine gerçekleştirilmez ki) echo "$'x'"çıkışları $'x'OPSIX'deki başına belirtilmemiş olsa tüm kabuklarda) ve onun genişleme bölünmüş tabi değildir + glob, bir teklif operatörüne genişleme operatörüne göre kesinlikle daha yakın.

IFS=\nIFS açardı n( \bir alıntı operatörü olarak kabul edilir) ve IFS="\n"ya da IFS='\n'iki karakter ve kullanılan karakterler için IFS açardı n.

Ayrıca kullanabilirsiniz:

IFS='
'

veya

IFS="
"

veya

IFS=$'
'

Daha az okunaklı olsa, bir hazır yeni satır geçmek için (ve bir gibi şeyler kullanmak yerine diğer göremiyorum set listiçinde violsun $IFSo kodda diğer aralık karakterler içeriyor).

IFS=:, IFS=':', IFS=":", IFS=$':'Tüm set IFS :kullandığınız önemli değil bu yüzden.

$'...': en az göre (çeşitleri) desteklenir ksh93, zsh, bash, mksh, BusyBox sh, FreeBSD sh. ksh93ve taşınabilir ve güvenilir bir şekilde dağıtmak ve kullanmak zahmetli olduğu için nadiren kullanıldığı halde, metnin yerelleştirilmesi için kullanılan bashbir $"..."tırnak biçimine de sahiptir .

esVe fishkabukları da kullanabilirsiniz \nyeni satır genişletmek için tırnak dışında.

Bazı araçlar printf, bazı uygulamalar echoveya awkbunları \nkendi başlarına genişletebilirler . Örneğin, aşağıdakiler yapılabilir:

printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only

yeni satır karakteri çıktısına dikkat edin, ancak şunu unutmayın:

IFS = $ (printf '\ n')

command substitution ( $(...)) tüm satırsonu karakterlerini ayırdığı için çalışmaz . Ancak şunları kullanabilirsiniz:

eval "$(printf 'IFS="\n"')"

Hangi satır printfsonu çıktısı bir "karakter, bir satırsonu değil çünkü çalışır .

Şimdi, bütünlük için, rckabuk ve türevlerde ( esveya gibi akanga) $'\n'gerçekten de bu \ndeğişkenin genişlemesi (adı iki karakterin dizisi olan bir değişken \ve n). Bu kabuklar değişken adları içeren ve yalnızca tırnak bir tür olabilir hangi karakterleri üzerinde bir sınırlama yoktur: '...'.

$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo

rcdeğişkenlerin tümü de ortama aktarılır, ancak en azından ortam değişkeni sürümü rcgibi değişken adları için Unix varyantında \nbir kodlama biçimi uygulanır:

; env | grep foo | sed -n l
__5cn=foo\001bar$

( 0x5cASCII'nin bayt değeri olmak üzere \; bu dizi değişkeninin ayırıcı olarak 0x1 bayt ile nasıl kodlandığını da görün).


1
+1olağan insanlık dışı bilgi seviyesi için
Steven Penny

10

Bu , ANSI-Cı alıntı :

Formdaki kelimeler $'string'özel olarak ele alınır. Sözcük string, ters eğik çizgiden kaçan karakterlerin ANSI C standardında belirtildiği gibi değiştirilmesiyle genişler .

Böylece $'\n'bir satırsonu gelir.

Bu, kullanımına rağmen kabuk parametresi genişlemesi ile ilgisizdir $.


6

Gibi dizeler POSIX standardı $'\n'tarafından tanıtılmıştır ksh93ve şu anda POSIX standardının bir parçası değildir.

Çoğu C benzer kaçışını, örneğin $'\u2345'desteklediği kaçışları kullanmaya izin verirler echo.

Bu kaçış yöntemini kullanmayı sevmiyorsanız (ksh93 veya bash durumunda), yine de kullanabileceğinizi unutmayın:

IFS='
'

ki bu eşdeğer ama okunması daha zor.

BTW: Bu uzantı zaten POSIX standart komitesini geçti, ancak 2020 yılından önce görünmemesi beklenen SUSv8 için planlandı , çünkü ilk önce mevcut hata listesinin arkasındaki gecikmemiz üzerinde çalışmamız gerekiyor.


$'...'Açılımları arasında ne fark echo. Daha çok biçim argümanı için olanlara benziyorlar printf. Çünkü echo, \0123for $'...'ve printfformat için 0 gerekiyorsa, bir satırsonu 3 ile yeni bir satır \0123olur \012.
Stéphane Chazelas

1
Not $'...'özellikleri hala tartışmalıdır. Şu anda önerilen ifadelerle hala çözülmesi gereken birkaç konu var.
Stéphane Chazelas

IIRC, Kapatıldı ancak tekrar açıldı. Etkili hale gelmeden önce hala çok zaman olduğu için, bununla ilgili gerçek bir sorun görmüyorum.
schily

1
Kapatıldı, birkaç itirazda bulundum, yeniden açıldı, daha sonra değiştirildi, hala birkaç sorun var (çoğu \uxxxxgenişleme ile ilgili) ve mevcut uygulamaları barındıracak bir çözüm yok. Bu yüzden bir sonraki POSIX sürümüne getirmeyebilir. Belki \uxxxxgenişleme sorunu8 için dışarıda bırakabilirler, bu yüzden hala en azından yapabiliriz $'\n'.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.