Wie teilt man einen String mit bash in zwei gleich lange Teilstrings?


12

Ich möchte eine Zeichenfolge in zwei Hälften teilen und nacheinander drucken. Beispielsweise:

abcdef

in

abc
def

Gibt es eine einfache Möglichkeit, dies zu tun, oder muss eine Zeichenfolge verarbeitet werden?


Wie hast du den eingehenden String? Variable? Stdin? Andere?
— Jeff Schaller

1
In einer Variablen. Es ist nicht wirklich wichtig, da alles ausgearbeitet werden kann (Standardeingabe kann in eine Variable eingegeben werden).
— Gabriel Diego

Es ist wichtig für die Effizienz, besonders wenn es möglicherweise gigantisch sein kann. Und auch der Einfachheit halber.
— Peter Cordes

Antworten:


16

Verwendung Parameter Expansion und Shell Arithmetik :

Die erste Hälfte der Variablen ist:

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

Die zweite Hälfte der Variablen ist:

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

so könnten Sie verwenden:

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

Sie können auch den folgenden awk-Befehl verwenden:

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

Danke für die Antwort!
— Gabriel Diego

prägnante und elegante Lösung.
— Dudi Boy

3
Sie können das loswerden $((...)); Der offund lenTeil der ${var:off:len}Substitution werden bereits als arithmetische Ausdrücke ausgewertet. Beispiel: foo=01234567; echo "${foo:0:${#foo}/2} ${foo:${#foo}/2}". Das ist dokumentiert und es ist dasselbe in zshund ksh93wie in Bash.
— Mosvy

3
Hinweis: Wenn die Länge der Zeichenfolge ungerade ist, wird sie dennoch in zwei Teile geteilt, während der zweite Buchstabe länger ist.
— peterh

8

Verwenden Sie splithier Zeichenfolgen und Befehlsersetzung:

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

7

Ein anderes awkSkript kann sein:

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

1
Beachten Sie, dass es mit mawk oder busybox awk nicht funktioniert, da die Syntax von division /und /ERE/Operator nicht eindeutig ist und der Sonderfall ()optional ist length(in diesem Fall sind diese Implementierungen jedoch nicht POSIX-kompatibel). Verwenden length()oder length($0)hier anstelle von lengthwürde für diejenigen helfen. Sie könnten auch awk 'BEGIN{half = int(length(ARGV[1]) / 2); print substr(ARGV[1], 1, half) ORS substr(ARGV[1], half+1)}' abcdefdie Pipe und den zusätzlichen Prozess speichern und zum Funktionieren bringen, selbst wenn die Zeichenfolge Zeilenumbrüche enthält.
— 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.

Beispielsweise,

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

Wenn die Zeichenfolge keine gerade Zahl ist, ist die zweite Zeile länger. Z.B

$ echo abcdefg | python3 -c 's = input(); x= len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
defg
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.