Bir sınırlayıcının ilk oluşumuna göre dizgiyi bölme


54

Bir sonraki formatta bir dize var

id;some text here with possible ; inside

ve ilk cereyan edişiyle onu 2 dizeye bölmek istiyorum ;. Yani, olmalı: idvesome text here with possible ; inside

Dize nasıl bölüneceğini biliyorum (örneğin, ile cut -d ';' -f1), ancak ;sol bölümün içindeyken daha fazla bölüme ayrılacak .


Dize bölündükten sonra "id" ile ne yapmak istersiniz? Bir değişkene atamak, yazdırmak, vb. İstiyor musunuz?
Kaos Daemon,

2 değişkene sahip olacağım: idvestring
gakhov

Ayrıca bkz. Metni işlemek
Wildcard

Yanıtlar:


65

cut Bunun için uygun bir araç gibi geliyor:

bash-4.2$ s='id;some text here with possible ; inside'

bash-4.2$ id="$( cut -d ';' -f 1 <<< "$s" )"; echo "$id"
id

bash-4.2$ string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string"
some text here with possible ; inside

Ancak readdaha da uygun:

bash-4.2$ IFS=';' read -r id string <<< "$s"

bash-4.2$ echo "$id"
id

bash-4.2$ echo "$string"
some text here with possible ; inside

3
Harika! Mucizevi şekilde çalışır! Ben readkullanıyorum beri seçeceğim bash. @ Manatwork teşekkür ederiz!
gakhov

cut"$ S" satır karakterlerini içermiyorsa yaklaşım sadece çalışacaktır. Bourne benzeri bir kabukta okunuyor. <<< bash ve ksh93'ün rc, zsh ve son sürümlerindedir ve standart olmayan bir sürümdür.
Stéphane Chazelas

Hata! @StephaneChazelas haklısın. Aklım oldu -abahsederken nedense bashs' read. (Burada kullanımsız olduğu
açıkça görülüyor

$ S de newline karakterleri içeriyorsa, okuma yaklaşımının işe yaramadığını söylemeyi unuttum. Kendi cevabımı ekledim.
Stéphane Chazelas

1
Ben de sondaki çizgi vurgulamak istiyorum -f 2-içinde string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string"komuta. Bu, çıktı için dizedeki sınırlayıcıların geri kalanını yok sayar. cut
Steen

17

Herhangi bir standart sh ile (bash dahil):

sep=';'
case $s in
  (*"$sep"*)
    before=${s%%"$sep"*}
    after=${s#*"$sep"}
    ;;
  (*)
    before=$s
    after=
    ;;
esac

readtabanlı çözümler, $sepboşluk, sekme veya yeni satır dışındaki tek karakter (ve bazı kabukları, tek bayt) değerleri için işe yarar ve yalnızca $syeni satır karakterleri içermiyorsa çalışır.

cuttabanlı çözümler yalnızca $syeni satır karakterleri içermiyorsa işe yarar .

sedTüm köşe kasalarını herhangi bir değerle ele alan çözümler tasarlanabilir $sep, ancak bunun için kabuğun içinde yerleşik bir destek varken o kadar ileri gitmeye değmez.


6

Bahsettiğiniz gibi, değerleri id ve string'e atamak istiyorsunuz.

önce şablonunuzu bir değişkene atayın (str)

    str='id;some text here with possible ; inside'
    id=${str%%;} 
    string=${str#;}

Artık değerlerinizi ilgili değişkenlerde bulabilirsiniz


Eğer kalıbınızı bir komuttan alıyorsanız set - kullanın some_command, o zaman kalıbınız 1 $ içinde saklanır ve yukarıdaki kodu str yerine 1 ile kullanırsınız
user1678213

Bu cevap @StephaneChazelas'tan ne kadar farklı?
Bernhard

4

Diğer çözümlere ek olarak, aşağıdakileri regextemel alan bir şey deneyebilirsiniz :

a="$(sed 's/;.*//' <<< "$s")"
b="$(sed 's/^[^;]*;//' <<< "$s")"

veya tam olarak ne yapmaya çalıştığınıza bağlı olarak,

sed -r 's/^([^;]*);(.*)/\1 ADD THIS TEXT BETWEEN YOUR STRINGS \2/'

nerede \1ve \2sen isteyen iki alt dizeleri içerir.


1

Standart baskıda çözüm:

    text='id;some text here with possible ; inside'
    text2=${text#*;}
    text1=${text%"$text2"}

    echo $text1
    #=> id;
    echo $text2
    #=> some text here with possible ; insideDD
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.