Bagaimana cara membagi string menjadi dua substring dengan panjang yang sama menggunakan bash?


12

Saya ingin membagi string menjadi dua bagian dan mencetaknya secara berurutan. Sebagai contoh:

abcdef

ke

abc
def

Apakah ada cara sederhana untuk melakukannya, atau perlu beberapa pemrosesan string?


Bagaimana Anda memiliki string yang masuk? Variabel? Stdin? Lain?
— Jeff Schaller

1
Dalam sebuah variabel. Tidak masalah, karena apa pun dapat dikerjakan (input stdin dapat dimasukkan ke dalam variabel).
— Gabriel Diego

Itu penting untuk efisiensi, terutama jika itu bisa jadi sangat besar. Dan juga untuk kenyamanan.
— Peter Cordes

Jawaban:


16

Menggunakan ekspansi parameter dan aritmatika shell :

Paruh pertama dari variabel tersebut adalah:

${var:0:${#var}/2}

Paruh kedua variabel adalah:

${var:${#var}/2}

jadi kamu bisa menggunakan:

printf '%s\n' "${var:0:${#var}/2}" "${var:${#var}/2}"

Anda juga bisa menggunakan perintah awk berikut:

awk 'BEGIN{FS=""}{for(i=1;i<=NF/2;i++)printf $i}{printf "\n"}{for(i=NF/2+1;i<=NF;i++){printf $i}{printf "\n"}}'

$ echo abcdef | awk 'BEGIN{FS=""}{for(i=1;i<=NF/2;i++)printf $i}{printf "\n"}{for(i=NF/2+1;i<=NF;i++){printf $i}{printf "\n"}}'
abc
def

Terima kasih atas tanggapannya!
— Gabriel Diego

solusi ringkas dan elegan.
— Dudi Boy

3
Anda dapat menyingkirkan $((...)); yang offdan lenbagian dari ${var:off:len}substitusi sudah dievaluasi sebagai ekspresi aritmatika. Contoh: foo=01234567; echo "${foo:0:${#foo}/2} ${foo:${#foo}/2}". Itu didokumentasikan, dan itu sama di zshdan ksh93seperti di bash.
— Mosvy

3
Catatan: Jika panjang string aneh, ini masih akan membaginya menjadi dua bagian, tetapi yang kedua akan menjadi karakter yang lebih panjang.
— peterh

8

Menggunakan split, di sini string dan substitusi perintah:

var=abcdef
printf '%s\n' "$(split -n1/2 <<<$var)" "$(split -n2/2 <<<$var)"

7

awkSkrip lain dapat berupa:

echo abcdef | awk '{print substr($0,1,length/2); print substr($0,length/2+1)}'

1
Perhatikan bahwa itu tidak bekerja dengan mawk atau busybox awk karena ambiguitas sintaksis dari divisi /dan /ERE/operator, dan kasus khusus ()sebagai opsional untuk length(masih implementasi yang tidak sesuai dengan POSIX dalam kasus itu). Menggunakan length()atau di length($0)sini bukannya lengthakan membantu mereka. Anda juga bisa melakukan awk 'BEGIN{half = int(length(ARGV[1]) / 2); print substr(ARGV[1], 1, half) ORS substr(ARGV[1], half+1)}' abcdefyang akan menyimpan pipa dan proses tambahan dan membuatnya berfungsi bahkan jika string tersebut mengandung karakter baris baru.
— Stéphane Chazelas

1

Python 3

s = input()  # Take one line of input from stdin.
x = len(s) // 2  # Get middle of string. "//" is floor division
print(s[:x], s[x:], sep="\n")  # Print "s" up to "x", then "s" past "x", joined on newlines.

Sebagai contoh,

$ echo abcdef | python3 -c 's = input(); x = len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
def

Jika panjang string bukan angka genap, baris kedua akan lebih panjang. Misalnya

$ echo abcdefg | python3 -c 's = input(); x= len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
defg
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.