Entfernen Sie die Zeichen rechts vom ersten Leerzeichen in Bash


8
2492  some string continues here

Ich möchte dies in konvertieren

2492

in Bash. Wie würde ich das machen?

Das fühlt sich eng an, funktioniert aber nicht:

var="2492  some string continues here  "
echo ${var%[[:space:]]*}

Wird es niemals führende Leerzeichen geben?
Alexander

Wenn Sie fragen, wie es in Bash gemacht werden soll, sollten Sie Bash wahrscheinlich nicht verwenden, um es zu machen. Benutze Perl oder so.
Ben

Antworten:


14

Weil Sie mehrere Leerzeichen verwenden möchten

${var%%[[:space:]]*}
# ...^^

um den längsten nachfolgenden Teilstring zu entfernen , der mit einem Leerzeichen beginnt

Mit nur einem %Zeichen entfernen Sie die kürzeste Folge eines Leerzeichens, gefolgt von null oder mehr Zeichen. Dies ist nur das letzte Leerzeichen in der Zeichenfolge.

$ echo ">$var<"; echo ">${var%[[:space:]]*}<"; echo ">${var%%[[:space:]]*}<"
>2492  some string continues here  <
>2492  some string continues here <
>2492<

Wenn Sie nur nach dem ersten Wort suchen , können Sie dies tun:

read -r word rest_of_string <<<"$var"
echo "I have: $word"

Dies kümmert sich um führende Leerzeichen, vorausgesetzt, Sie haben die IFS-Variable nicht geändert.


Wie wäre es, wenn die Zeichenfolge ein führendes Leerzeichen enthält? `2492 hier geht eine Saite weiter`
Joshua Soileau

Dadurch werden alle Zeichen entfernt.
Glenn Jackman

[:space:]Die Zeichenklasse umfasst Leerzeichen, Tabulatoren, CR, NL usw. Es ist also ein Allheilmittel für jedes Leerzeichen.
Glenn Jackman

1
a=($var); echo "${a[0]}"funktioniert auch für den Zugriff auf das erste Wort bei führenden Leerzeichen.
Digitales Trauma

Sie setzen den Wert der Dateinamenerweiterung sowie der set -f
Wortaufteilung aus

3

Es gibt die einfache Lösung, %%( ${var%% *}) anstelle von %( ${var% *}) zu verwenden. Dadurch wird *nach einem anfänglichen Leerzeichen alles ( ) entfernt.

$ var='2492  some string continues here'
$ echo "${var%% *}"
2492

Dies schlägt jedoch fehl, wenn die Zeichenfolge in var führende Leerzeichen enthält. Es ist möglich, die führenden Leerzeichen zu entfernen mit:

$ var=$' \t 2492  some string continues here  '
$ var="${var#"${var%%[![:space:]]*}"}"
$ echo "$var"
2492  some string continues here  
$ echo "${var%%[[:space:]]*}"
2492

Dies funktioniert auch dann, wenn die Leerzeichen Leerzeichen-Registerkarten NL oder CR sind.


Regex

Eine robustere Lösung ist möglicherweise die Verwendung eines regulären Ausdrucks:

$ var=$' \t 2492  some string continues here  '
$ regex='^[[:space:]]*([^[:space:]]+)'
$ [[ $var =~ $regex ]] && var=${BASH_REMATCH[1]}
$ echo "$var"
2492

1
Ich denke, das ist das erste Mal, dass ich jemanden sehe, der reguläre Ausdrücke als "robuster" bezeichnet ;-)
Kusalananda

2

Sie können auch das einfache Werkzeug verwenden cut, das Zeichenfolgen basierend auf einem Trennzeichen schneidet:

echo "$mystring" | cut -d' ' -f 1 

Wo :

  • -d' ' Setzt das Trennzeichen auf ein Leerzeichen
  • -f 1 gibt das erste Feld an (basierend auf dem Trennzeichen)

Ich mag diesen. Keine regulären Ausdrücke, keine Programmiersprachen.
Gronostaj

1

Sie können die native Shell-String-Manipulation verwenden:

TEST="test  1234 foo"
SPLIT_VAR=${TEST/ */ }

Es ersetzt das erste Muster, das mit "*" übereinstimmt (ein Leerzeichen, dann irgendetwas), und ersetzt es durch "" (ein Leerzeichen). Sie behalten also das erste Wort und das erste Leerzeichen.

Weitere Informationen zur Verwendung der Zeichenfolgenmanipulation finden Sie unter http://www.tldp.org/LDP/abs/html/string-manipulation.html .

Und als Randnotiz, es funktioniert auch weniger entwickelte Shell (getestet auf der Ash-Implementierung von Busybox).


0

Um nur Bash- und integrierte Befehle zu verwenden, können Sie IFS ( Internal Field Seperator ) und Arrays verwenden

set -f                # To prevent filename globbing when creating the array, as pointed out by Kusalananda in the comments
array=(2492 some string continues here)
set +f                # enable it again
IFS=" "
echo "${array[0]}"
unset IFS

Versuchen Sie das mit einer Zeichenfolge, die z *.
Kusalananda

@Kusalananda versuchte es mit array=(*2492* *some * *string continues* here)- funktioniert immer noch
Robert Riedl

Fügen Sie nun eine Datei in das aktuelle Verzeichnis ein, die beispielsweise 2492den Namen enthält myfile-2492.txt, und führen Sie sie erneut aus.
Kusalananda

1
@Kusalananda oh wow, warum passiert das?
Robert Riedl

1
@Kusalananda, ich denke ich muss mit beginnen set -fund enden mit set +f?
Robert Riedl

0

Wenn Ihnen ein externer Anruf nichts ausmacht, verwenden Sie awk oder sed:

$ string="first second third fourth"
$ echo "${string}" | awk '{print $1}' # will work even with tabs
first
$ echo "${string}" | sed -e "s/ .*$//" # will fail on leading whitespace
first


Zitiert meine Saiten, danke, dass Sie @Kusalananda gefangen haben
anonym bei der Arbeit
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.