Jak znaleźć ostatnie pole za pomocą 'cut'

Bez za pomocą sed LUB awk, tylko cut, Jak uzyskać ostatnie pole, gdy liczba pól jest nieznana lub zmienia się z każdą linią?

 356
Author: Benjamin W., 2014-03-29

12 answers

Możesz spróbować czegoś takiego:

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

Wyjaśnienie

  • rev odwraca "maps.google.com" być moc.elgoog.spam
  • cut używa dot (ie '.') jako ogranicznik i wybiera pierwsze pole, które jest moc
  • na koniec odwracamy go ponownie, aby uzyskać com
 781
Author: zedfoxus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-06 21:02:43

Użyj rozszerzenia parametru. Jest to znacznie bardziej wydajne niż jakiekolwiek zewnętrzne polecenie, cut (lub grep).

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

Zobacz BashFAQ #100 aby zapoznać się z wprowadzeniem do natywnej manipulacji łańcuchami w bashu.

 135
Author: Charles Duffy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-29 05:15:24

Nie jest możliwe użycie tylko cut. Oto sposób użycia grep:

grep -o '[^,]*$'

Zastąp przecinek dla innych ograniczników.

 105
Author: tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-29 05:03:26

Bez awk ?... Ale to takie proste z awk:

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

AWK to o wiele potężniejsze narzędzie, które możesz mieć w kieszeni. - F jeśli dla separatora pola NF jest liczbą pól (również oznacza indeks ostatniego)

 61
Author: Amir Mehler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-30 08:19:52

Istnieje wiele sposobów. Możesz też tego użyć.

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

Oczywiście, wejście spacji dla polecenia tr powinno zostać zastąpione ogranicznikiem, którego potrzebujesz.

 19
Author: rjni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 21:37:30

Jest to jedyne rozwiązanie możliwe do użycia tylko przy cięciu:

Echo "s. t. r. I. n. g. "/ cut-d'."- f2- [repeat_following_part_forever_or_until_out_of_memory:] | cut-d'."- f2 -

Używając tego rozwiązania, liczba pól może być rzeczywiście nieznana i zmieniać się od czasu do czasu. Ponieważ jednak długość linii nie może przekraczać znaków lub pól LINE_MAX, w tym znaku nowej linii, wtedy dowolna liczba pól nigdy nie może być częścią jako rzeczywisty warunek To rozwiązanie.

Tak, bardzo głupie rozwiązanie, ale jedyne, które spełnia kryteria, jak sądzę.

 8
Author: A friend,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 20:22:58

Jeśli twój łańcuch wejściowy nie zawiera ukośników do przodu, możesz użyć basename i subshell:

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

To nie używa sed ani awk, ale również nie używa cut, więc nie jestem pewien, czy kwalifikuje się jako odpowiedź na pytanie w jego słowach.

To nie działa dobrze, jeśli przetwarzanie ciągów wejściowych, które mogą zawierać ukośniki. Obejściem tej sytuacji byłoby zastąpienie ukośnika innym znakiem, o którym wiesz, że nie jest częścią ważnego input string. Na przykład znak pipe (|) jest również niedozwolony w nazwach plików, więc to zadziała:

$ basename "$(echo 'maps.google.com/some/url/things' | tr '/' '|' | tr '.' '/')" | tr '|' '/'
 4
Author: jstine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 13:20:58

Następujące implementacje sugestia przyjaciela

#!/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
Author: user2166700,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 18:55:49

Jeśli Masz plik o nazwie filelist.txt, który jest listą ścieżek takich jak:: c:/dir1/dir2/file1.h c:/dir1/dir2/dir3/file2.h

Wtedy możesz to zrobić: rev filelist.txt/ cut-d" | "- f1 / rev

 0
Author: aperson1961,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-07 06:01:38

Dodanie podejścia do tego starego pytania tylko dla zabawy:

$ 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

Oprócz bash, tylko cut jest używany. I chyba echo.

 0
Author: Kaffe Myers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-24 09:12:00

Alternatywą używającą Perla byłoby:

perl -pe 's/(.*) (.*)$/$2/' file

Gdzie można zmienić \t na dowolny ogranicznik file

 0
Author: moni905,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-04 00:07:58

Zdałem sobie sprawę, że jeśli tylko zapewnimy istnienie ogranicznika, to zadziała. Tak więc w moim przypadku mam przecinki i ograniczniki spacji. Dodaję spację na końcu;

$ ans="a, b"
$ ans+=" "; echo ${ans} | tr ',' ' ' | tr -s ' ' | cut -d' ' -f2
b
 -1
Author: AnneTheAgile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-15 07:55:17