Memisahkan string dengan munculnya pembatas pertama


54

Saya memiliki string dalam format selanjutnya

id;some text here with possible ; inside

dan ingin membaginya menjadi 2 string dengan kemunculan pertama ;. Jadi, seharusnya: iddansome text here with possible ; inside

Saya tahu cara memisahkan string (misalnya, dengan cut -d ';' -f1), tetapi akan terpecah menjadi lebih banyak bagian karena saya memiliki ;di dalam bagian kiri.


Setelah string terpecah, apa yang ingin Anda lakukan dengan "id"? Apakah Anda ingin menetapkannya ke variabel, mencetaknya, dll?
Daemon of Chaos

Saya akan memiliki 2 variabel: iddanstring
gakhov

Jawaban:


65

cut terdengar seperti alat yang cocok untuk ini:

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

Tetapi readbahkan lebih cocok:

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
Bagus! Itu bekerja seperti pesona! Saya akan memilih readkarena saya menggunakan bash. @Manatwork terima kasih!
gakhov

The cutPendekatan hanya akan bekerja ketika "$ s" tidak mengandung karakter baris baru. baca dalam shell seperti Bourne. <<< dalam rc, zsh dan versi terbaru dari bash dan ksh93 dan merupakan salah satu yang tidak standar.
Stéphane Chazelas

Ups, Anda benar @StephaneChazelas. Pikiran saya berada di -auntuk beberapa alasan ketika menyebutkan bash's read. (Jelas tidak ada gunanya di sini.)
manatwork

Saya lupa menyebutkan bahwa pendekatan baca tidak berfungsi jika $ s juga mengandung karakter baris baru. Saya telah menambahkan jawaban saya sendiri.
Stéphane Chazelas

1
Saya ingin menekankan tanda hubung di -f 2-dalam string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string"perintah. Inilah yang mengabaikan sisa pembatas dalam string untuk hasil cetak. Tidak jelas ketika melihat halaman manualcut
Steen

18

Dengan sh standar apa saja (termasuk bash):

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

readsolusi berbasis akan bekerja untuk nilai karakter tunggal (dan dengan beberapa shell, byte tunggal) $sepselain spasi, tab atau baris baru dan hanya jika $stidak mengandung karakter baris baru.

cutsolusi berbasis hanya akan berfungsi jika $stidak mengandung karakter baris baru.

sedsolusi dapat dirancang yang menangani semua kasus sudut dengan nilai apa pun $sep, tetapi tidak layak untuk sejauh itu ketika ada dukungan built-in di shell untuk itu.


6

Seperti yang telah Anda sebutkan bahwa Anda ingin menetapkan nilai ke id dan string

pertama-tama tetapkan pola Anda ke variabel (mis. str)

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

Sekarang Anda memiliki nilai dalam variabel masing-masing


jika Anda mendapatkan pola dari perintah lalu gunakan set - some_command, maka pola Anda akan disimpan dalam $ 1 dan menggunakan kode di atas dengan 1 alih-alih str
user1678213

1
Bagaimana jawaban ini berbeda dari @StephaneChazelas?
Bernhard

4

Selain solusi lain, Anda dapat mencoba sesuatu regexberdasarkan:

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

atau tergantung pada apa yang Anda coba lakukan dengan tepat, Anda bisa menggunakannya

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

di mana \1dan \2berisi dua substring yang Anda inginkan.


1

Solusi dalam bash standar:

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

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