it-swarm.com.de

So finden Sie das letzte Feld mit 'Ausschneiden'

Ohne mit sed oder awk, only cut, wie bekomme ich das letzte Feld, wenn die Anzahl der Felder unbekannt ist oder sich mit jeder Zeile ändert?

204
noobcoder

Sie könnten so etwas versuchen:

echo 'maps.google.com' | rev | cut -d'.' -f 1 | rev

Erklärung

  • die Umkehrung von maps.google.com wird moc.elgoog.spam sein.
  • cut verwendet Punkt als Trennzeichen und wählt das erste Feld aus, das moc ist.
  • zum Schluss kehren wir es noch einmal um (danke für die Erinnerung, @tom), um com
472
zedfoxus

Verwenden Sie eine Parametererweiterung. Dies ist viel effizienter als jede Art von externem Befehl, cut (oder grep).

data=foo,bar,baz,qux
last=${data##*,}

In BashFAQ # 100 finden Sie eine Einführung in die native String-Bearbeitung in bash.

99
Charles Duffy

Es ist nicht möglich, nur cut zu verwenden. Hier ist eine Möglichkeit, grep zu verwenden:

grep -o '[^,]*$'

Ersetzen Sie das Komma für andere Trennzeichen.

67
tom

Ohne awk ... ... Aber mit awk ist es so einfach:

echo 'maps.google.com' | awk -F. '{print $NF}'

AWK ist ein viel leistungsfähigeres Werkzeug, das Sie in Ihrer Tasche haben können.

18
Amir Mehler

Es gibt mehrere Möglichkeiten. Sie können dies auch verwenden.

echo "Your string here"| tr ' ' '\n' | tail -n1
> here

Natürlich muss die Leerzeicheneingabe für den Befehl tr durch das Trennzeichen ersetzt werden, das Sie benötigen.

12
rjni

Dies ist die einzige Lösung, die nur für das Schneiden geeignet ist:

echo "s.t.r.i.n.g." | cut -d '.' -f2 - [repeat_following_part_forever_or_until_out_of_memory:] | cut -d '.' -f2-

Bei dieser Lösung kann die Anzahl der Felder tatsächlich unbekannt sein und von Zeit zu Zeit variieren. Da die Zeilenlänge jedoch LINE_MAX-Zeichen oder -Felder einschließlich des Zeichens für neue Zeilen nicht überschreiten darf, kann eine beliebige Anzahl von Feldern niemals Bestandteil der Lösung sein.

Ja, eine sehr dumme Lösung, aber die einzige, die die Kriterien erfüllt, die ich denke.

6
A friend

die folgenden Geräte Vorschlag eines Freundes

#!/bin/bash
rcut(){

  nu="$( echo $1 | cut -d"$DELIM" -f 2-  )"
  if [ "$nu" != "$1" ]
  then
    rcut "$nu"
  else
    echo "$nu"
  fi
}

$ export DELIM=.
$ rcut a.b.c.d
d
2
user2166700

Wenn Sie über eine Datei namens filelist.txt verfügen, handelt es sich dabei um folgende Listenpfade: C: /dir1/dir2/file1.h

dann können Sie dies tun: rev filelist.txt | cut -d "/" -f1 | rev

0
aperson1961

Wenn Ihre Eingabezeichenfolge keine Schrägstriche enthält, können Sie basename und eine Subshell verwenden:

$ basename "$(echo 'maps.google.com' | tr '.' '/')"

Dies verwendet nicht sed oder awk, aber auch cut nicht. Daher bin ich mir nicht ganz sicher, ob sie als formulierte Antwort auf die Frage qualifiziert ist.

Dies funktioniert nicht gut, wenn Eingabezeichenfolgen verarbeitet werden, die Schrägstriche enthalten können. Um dieses Problem zu umgehen, können Sie den Schrägstrich durch ein anderes Zeichen ersetzen, von dem Sie wissen, dass es nicht Teil einer gültigen Eingabezeichenfolge ist. Zum Beispiel ist das Pipe-Zeichen (|) auch in Dateinamen nicht zulässig, daher würde dies funktionieren:

$ basename "$(echo 'maps.google.com/some/url/things' | tr '/' '|' | tr '.' '/')" | tr '|' '/'
0
jstine

Hinzufügen eines Ansatzes zu dieser alten Frage nur zum Spaß:

$ cat input.file # file containing input that needs to be processed
a;b;c;d;e
1;2;3;4;5
no delimiter here
124;adsf;15454
foo;bar;is;null;info

$ cat tmp.sh # showing off the script to do the job
#!/bin/bash
delim=';'
while read -r line; do  
    while [[ "$line" =~ "$delim" ]]; do
        line=$(cut -d"$delim" -f 2- <<<"$line")
    done
    echo "$line"
done < input.file

$ ./tmp.sh # output of above script/processed input file
e
5
no delimiter here
15454
info

Neben Bash wird nur Cut verwendet. Nun, und Echo, denke ich.

0
Kaffe Myers

Ich habe erkannt, dass es funktioniert, wenn wir nur sicherstellen, dass ein nachlaufendes Trennzeichen existiert. In meinem Fall habe ich also Kommas und Leerzeichen als Trennzeichen. Ich füge am Ende ein Leerzeichen hinzu. $ ans="a, b" $ ans+=" "; echo ${ans} | tr ',' ' ' | tr -s ' ' | cut -d' ' -f2 b

0
AnneTheAgile