Как разделить строку в оболочке и получить последнее поле



Предположим у меня есть строка 1:2:3:4:5 и я хочу получить его последнее поле (5 в данном случае). Как мне это сделать с помощью Bash? Я пытался cut, но я не знаю, как указать последнее поле с -f.

650   14  

14 ответов:

можно использовать операторы строку:

$ foo=1:2:3:4:5
$ echo ${foo##*:}
5

это обрезает все от фронта до':', жадно.

${foo  <-- from variable foo
  ##   <-- greedy front trim
  *    <-- matches anything
  :    <-- until the last ':'
 }

другой способ-повернуть вспять до и после cut:

$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef

Это позволяет очень легко получить предпоследнее поле или любой диапазон полей, пронумерованных с конца.

трудно получить последнее поле с помощью cut, но вот (один набор) решений в awk и perl

$ echo 1:2:3:4:5 | awk -F: '{print $NF}'
5
$ echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
5

предполагая довольно простое использование (например, без экранирования разделителя), вы можете использовать grep:

$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5

срыв - найти все символы не разделитель ([^:]) в конце строки ($). - o печатает только соответствующую деталь.

в одну сторону:

var1="1:2:3:4:5"
var2=${var1##*:}

другой, используя массив:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}

еще один с массивом:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}

использование регулярных выражений Bash (version >= 3.2):

var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}

используя sed:

$ echo '1:2:3:4:5' | sed 's/.*://' # => 5

$ echo '' | sed 's/.*://' # => (empty)

$ echo ':' | sed 's/.*://' # => (empty)
$ echo ':b' | sed 's/.*://' # => b
$ echo '::c' | sed 's/.*://' # => c

$ echo 'a' | sed 's/.*://' # => a
$ echo 'a:' | sed 's/.*://' # => (empty)
$ echo 'a:b' | sed 's/.*://' # => b
$ echo 'a::c' | sed 's/.*://' # => c
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e

просто переведите разделитель в новую строку и выберите последнюю запись с помощью tail -1.

Если ваше последнее поле является одним символом, вы можете сделать это:

a="1:2:3:4:5"

echo ${a: -1}
echo ${a:(-1)}

Регистрация работа со строками в bash.

С Помощью Bash.

$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo  $${#}
0
echo "a:b:c:d:e"|xargs -d : -n1|tail -1

сначала используйте xargs разделить его с помощью ":",- n1 означает, что каждая строка имеет только одну часть.Затем, Принг последнюю часть.

есть много хороших ответов здесь, но все же я хочу поделиться этим с помощью basename:

 basename $(echo "a:b:c:d:e" | tr ':' '/')
это не получится, если уже есть некоторые ' / ' в вашей строке. Если Слэш / является вашим разделителем, то вы просто должны (и должны) использовать basename.

Это не лучший ответ, но он просто показывает, как вы можете быть творческим, используя команды bash.

for x in `echo $str | tr ";" "\n"`; do echo $x; done

для тех, кто комфортно с Python, https://github.com/Russell91/pythonpy - это хороший выбор, чтобы решить эту проблему.

$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'

из справки pythonpy:-x treat each row of stdin as x.

С помощью этого инструмента легко написать код python, который применяется к входным данным.

решение с использованием встроенного чтения

IFS=':' read -a field <<< "1:2:3:4:5"
echo ${field[4]}

Comments

    Ничего не найдено.