'\ n' di `IFS = $ '\ n' adalah variabel?


12

Saya perhatikan bahwa untuk menetapkan baris baru IFSharus dengan awalan $ sebagai

IFS=$'\n'

tetapi jika diatur titik dua, adil

IFS=:

Apakah \nvariabel?

Jawaban:


21

Itu $'...'di bashtidak parameter ekspansi, itu adalah jenis khusus dari kutipan diperkenalkan oleh ksh93yang memperluas mereka \n, \x0a, \12kode untuk karakter baris baru. zshjuga ditambahkan \u000a. ksh93dan bashjuga memiliki \cjsementara zshmemiliki \C-J. ksh93juga mendukung variasi suka \x{a}.

Ini $adalah isyarat bahwa itu adalah suatu bentuk atau ekspansi. Tetapi bagaimanapun juga, ini berbeda dari bentuk ekspansi lain yang menggunakan $(seperti $((1 + 1)), $paramatau $(cmd)) dalam hal itu tidak dilakukan di dalam tanda kutip ganda atau dokumen di sini ( echo "$'x'"output $'x'di semua shell meskipun tidak ditentukan per POSIX) dan ekspansi tidak dapat dibagi + glob, ini pasti lebih dekat ke operator kutipan daripada operator ekspansi.

IFS=\nakan mengatur IFS ke n( \diperlakukan sebagai operator mengutip) dan IFS="\n"atau IFS='\n'akan mengatur IFS ke dua karakter backslash dan n.

Anda juga bisa menggunakan:

IFS='
'

atau

IFS="
"

atau

IFS=$'
'

Untuk lulus baris baru literal, meskipun itu kurang terbaca (dan satu tidak bisa melihat selain menggunakan hal-hal seperti set listdi viapakah $IFSmengandung karakter spasi lain dalam kode itu).

IFS=:, IFS=':', IFS=":", IFS=$':'Siap IFS untuk :jadi tidak masalah yang Anda gunakan.

$'...'didukung (dengan variasi) oleh setidaknya: ksh93, zsh, bash, mksh, busybox sh, FreeBSD sh. ksh93dan bashjuga memiliki $"..."bentuk kutipan yang digunakan untuk pelokalan teks meskipun jarang digunakan karena rumit untuk digunakan dan digunakan dengan mudah dan andal.

The esdan fishkerang juga dapat menggunakan \ndi luar tanda kutip untuk memperluas ke baris baru.

Beberapa alat seperti printf, beberapa implementasi echoatau awkjuga dapat mengembangkannya \nsendiri. Misalnya, seseorang dapat melakukan:

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

untuk menghasilkan karakter baris baru, tetapi perhatikan bahwa:

IFS = $ (printf '\ n')

tidak akan berfungsi karena substitusi perintah ( $(...)) menghapus semua karakter karakter baris baru. Namun Anda dapat menggunakan:

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

Yang berfungsi karena hasil printfakhir diakhiri dengan "karakter, bukan baris baru.

Sekarang, untuk kelengkapan, di rcshell dan turunannya (suka esatau akanga), $'\n'memang merupakan perluasan dari \nvariabel itu (variabel yang namanya adalah urutan dua karakter \dan n). Mereka kerang tidak memiliki batasan pada apa karakter nama variabel mungkin berisi dan hanya memiliki satu jenis kutipan: '...'.

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

rcvariabel juga semua diekspor ke lingkungan, tetapi setidaknya dalam varian Unix rc, untuk nama variabel seperti \n, versi variabel lingkungan mengalami bentuk pengkodean:

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

( 0x5cmenjadi nilai byte ASCII \; lihat juga bagaimana variabel array dikodekan dengan byte 0x1 sebagai pemisah).


1
+1untuk tingkat pengetahuan tidak manusiawi yang biasa
Steven Penny

10

Ini adalah kutipan ANSI-C :

Kata-kata dalam bentuk $'string'diperlakukan secara khusus. Kata diperluas ke string, dengan karakter backslash-escaped diganti sebagaimana ditentukan oleh standar ANSI C.

Dengan demikian $'\n'digantikan oleh baris baru.

Ini tidak terkait dengan ekspansi parameter shell , meskipun menggunakan $.


6

String seperti $'\n'telah diperkenalkan oleh ksh93dan saat ini bukan bagian dari standar POSIX.

Mereka memungkinkan untuk menggunakan sebagian besar C sama seperti escapes, misalnya $'\u2345'dan escapes yang juga didukung oleh echo.

Perhatikan bahwa jika Anda tidak suka (jika menggunakan ksh93 atau bash) untuk menggunakan metode melarikan diri itu, Anda masih dapat menggunakan:

IFS='
'

yang setara tapi lebih sulit dibaca.

BTW: Ekstensi ini telah melewati komite standar POSIX, tetapi dijadwalkan untuk SUSv8 yang diharapkan akan muncul tidak sebelum tahun 2020 karena kita pertama-tama perlu bekerja pada kelambatan kita di belakang daftar bug saat ini.


The $'...'ekspansi berbeda dari yang echo. Mereka lebih seperti yang untuk argumen formatprintf . Sebab echo, 0 diperlukan \0123sementara untuk $'...'dan printfformat, \0123akan menjadi \012baris baru diikuti oleh litteral 3.
Stéphane Chazelas

1
Perhatikan bahwa $'...' spesifikasinya masih dibahas. Ada beberapa masalah yang masih harus diselesaikan dengan kata-kata yang saat ini diusulkan.
Stéphane Chazelas

IIRC, ditutup tetapi telah dibuka kembali. Karena kenyataan bahwa masih ada banyak waktu sebelum menjadi efektif, saya tidak melihat masalah nyata dengan itu.
schily

1
Ditutup, saya mengajukan beberapa keberatan, dibuka kembali, kemudian diubah, masih ada beberapa masalah (sebagian besar tentang \uxxxxekspansi), dan tidak ada resolusi yang terlihat yang akan mengakomodasi implementasi yang ada. Jadi itu mungkin tidak membuatnya menjadi versi POSIX berikutnya. Mungkin mereka bisa membiarkan \uxxxxekspansi keluar untuk edisi 8, jadi kita masih bisa memiliki setidaknya $'\n'.
Stéphane Chazelas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.