Bash betiğinde IFS = $ '\ n' in anlamı nedir?


163

Bir bash kabuk betiğinin başında şu satır bulunur:

IFS=$'\n'

Bu semboller koleksiyonunun arkasındaki anlamı nedir?



vim sözdizimi bunu benim için bir hata olarak vurgular; düzeltmek?
theonlygusti

IFS=$'\n'bir faşizmdir (+ diğer kabuklar, ANSI-C Quoting'i kullanın , geçici çözümler için bkz. stackoverflow.com/questions/10748703/…
pevik

Yanıtlar:


199

IFS"iç alan ayırıcısı" anlamına gelir. Kabuk tarafından kelime bölmesinin nasıl yapıldığını, yani kelime sınırlarının nasıl tanınacağını belirlemek için kullanılır.

Bunu bash gibi bir kabuğun içinde deneyin (diğer kabukları bunu farklı şekilde idare edebilir, örneğin zsh):

mystring="foo:bar baz rab"
for word in $mystring; do
  echo "Word: $word"
done

İçin varsayılan değer IFS, boşluk karakterlerinden oluşur (kesin olarak: boşluk, sekme ve yeni satır). Her karakter bir kelime sınırı olabilir. Bu nedenle, varsayılan değeri olan IFSyukarıdaki döngü yazdırılır:

Word: foo:bar
Word: baz
Word: rab

Başka bir deyişle, kabuk boşlukların bir kelime sınırı olduğunu düşünür.

Şimdi, IFS=:döngüyü çalıştırmadan önce ayarı deneyin . Bu sefer sonuç:

Word: foo
Word: bar baz rab

Şimdi, kabuk mystringkelimelere ayrılıyor - ama şimdi, yalnızca bir kelimeye sınır kelimesi gibi davranıyor.

İlk karakteri IFSözeldir: Özel $*değişkeni kullanırken çıktıdaki kelimeleri sınırlandırmak için kullanılır (örneğin, bunun gibi özel değişkenler hakkında daha fazla bilgi bulabileceğiniz Advanced Bash Scripting Guide'dan alınmıştır ):

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

Karşılaştırmak:

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

Her iki örnekte de, kabuk hala karakterlerin tüm tedavi unutmayın :, -ve ;kelime sınırlarını. Değişen tek şey davranışlarıdır $*.

Bilinmesi gereken başka bir önemli şey de “IFS boşluk alanı” olarak adlandırılan işlemdir . Temel olarak IFS, boşluk karakterleri içerdiği anda , öncü ve sondaki boşluk boşlukları, işlenmeden önce ayrılacak dizeden çıkarılır ve ardışık boşluk karakterleri dizisi de alanları sınırlar. Ancak, bu yalnızca gerçekten içinde bulunan boşluk karakterleri için geçerlidir IFS.

Örneğin, dize bakalım "a:b:: c d "(sondaki boşluk ve iki boşluk karakterleri arasında cve d).

  1. İle IFS=:: Bu dört alan ürüne ayrılır "a", "b", ""(boş dize) ve " c d "(yine iki boşluk arasında cve d). Son alandaki baştaki ve sondaki boşlukları not edin.
  2. İle IFS=' :', beş alana bölünmelidir olacaktır: "a", "b", ""(boş dize), "c"ve "d". Hiçbir yerde lider ve iz bırakan boşluk yok.

Birden çok, ardışık boşluk karakterinin ikinci örnekte iki alanı sınırlandırdığını, ancak çok sayıda ardışık sütunun (boşluk karakterleri olmadığından) değişmediğini unutmayın.

Gelince IFS=$'\n', bu ise ksh93de desteklediği sözdiziminde bash, zsh, mkshve FreeBSD sh(bütün kabukları arasında varyasyonlar ile birlikte). Bash manpage'den alıntı:

$ 'String' formundaki kelimeler özel olarak değerlendirilir. Kelime "string" e genişler ve ANSI C standardında belirtildiği şekilde ters eğik çizgi karakterlerini değiştirir.

\nnewline için kaçış dizisidir, bu nedenle IFStek bir newline karakterine ayarlanır.


3
Bu iyi, ama bence, bashkomut dosyası kılavuzu yerine POSIX'in özelliklerini okumak ve anlamak için çok daha iyisini yaparsınız . Esas olarak, böyle bağlantılarda mevcut olan bilgiler önemli yollardan yoksundur. Her neyse, bu nedenle kabuk yarma ile ilgili iki önemli noktayı gözden kaçırıyor - globbing ve IFS boşluk.
mikeserv

@mikeserv Teşekkürler, IFS boşlukları hakkında biraz bilgi ekledim. Bunu bilmiyordum. :)
Tblue

4
O kadar alakalı değil, ama merak ediyorsanız unset IFS, bir kabuğun neye göre daha farklı davrandığını görmek isteyebilirsiniz IFS=. Ayrıca "${named_array[*]}"
IFS'teki

Birkaç nokta daha: 1- yönetilen sözcük bölme, $IFSliste bağlamında alıntılanmamış bir değişkeni genişletme üzerine gerçekleştirilen iki ana şeyden biridir ( operatörün bir splitparçasıdır split+glob). Diğeri kürek çekiyor. İş bölmesini kullanırken set -f, globbölümü devre dışı bırakmak için genellikle sorun çıkarmanız gerekir .
Stéphane Chazelas

3
3- $IFSayrıca readyerleşik komut tarafından da kullanılır
Stéphane Chazelas

22

Dolarlı tek tırnak içinde bazı karakterler özel olarak değerlendirilir. Örneğin, \nyeni satıra çevrilir.

Bu nedenle, bu belirli satır, IFS değişkenine yeni satır atar. IFS, sırayla bash: Dahili Alan Ayırıcı'da özel bir değişkendir. Gibi man bash, diyor

genişlemeden sonra sözcük bölmek ve readyerleşik komutla sözcükleri sözcüklere bölmek için kullanılır . Varsayılan değer <space><tab><newline>.


5
dollared single quotesBasit tek tırnak işaretlerinden farklı olan bahsetmek için +1 .
Snowcrash

2
@ Basit tek tırnak işaretlerinden farklı olan dolarlık tekli sözlerden bahsetmek için +1 deyince @Snowcrash +1 . Üzgünüm, yardımcı olamadım :) Ama aslında bunun belirtilmesi çok iyi bir şey çünkü önemli!
Pryftan

1
+1 için +1 için @Pryftan +1 ... bilirsin ... bu gerçekten önemli.
0xc0de

@ 0xc0de Kesinlikle katılıyorum! Bunun için teşekkürler! :)
Pryftan

15

Kısacası, değişkene IFS=$'\n'newline ata .\nIFS

$'string'yapı ANSI C benzeri kaçış dizilerinin kodunu çözmek için kullanılan bir alıntılama mekanizmasıdır. Bu sözdizimi geliyor ksh93ve benzeri çağdaş kabuğuna taşınabilir oldu bash, zsh, pdksh, busybox sh.

Bu sözdizimi POSIX tarafından tanımlanmadı, ancak SUS sorunu 7 için kabul edildi .


-1

$IFSÖrnek olarak açıklamayı tercih ettim :
Suppsoe, cp veya mv veya başka bir dosya işlemesi yapmak istiyorsanız, IFS kurallara göre boştur, Dosyalarınız meta karakterleri veya boşlukları olduğunda:
Linux Administration.pdfveya Free Software Fundation.ogg, Tabii ki, bir probula sahip olacaksınız, Çünkü: Linux bir ayrı param ve Administartion ayrı param olarak kabul eder. Yani bash vardır built-in variable, Sonra başlatabilirsiniz IFS==$(echo -en "\n\b"), Sonra bash, dosya adı arasındaki herhangi bir meta karakteri ve boşluğu atın.

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS
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.