Ответы:
Вы можете использовать строковые операторы :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
Это урезает все от фронта до «:», жадно.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
${foo%:*}
. #
- с начала; %
- с конца. #
, %
- кратчайший матч; ##
, %%
- самый длинный матч.
echo ${pwd##*/}
не работает.
pwd
как переменную. Попробуй dir=$(pwd); echo ${dir##*/}
. Работает для меня!
Другой способ - повернуть до и после cut
:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
Это позволяет легко получить последнее, кроме одного поля, или любой диапазон полей, пронумерованных с конца.
echo "1 2 3 4" | rev | cut -d " " -f1 | rev
rev
, что мне было нужно! cut -b20- | rev | cut -b10- | rev
Трудно получить последнее поле, используя cut, но вот некоторые решения в awk и perl
echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
/
символ: /a/b/c/d
и /a/b/c/d/
дают тот же результат ( d
) при обработке pwd | awk -F/ '{print $NF}'
. Принятый ответ приводит к пустому результату в случае/a/b/c/d/
/
качестве разделителя, и если ваш путь будет, /my/path/dir/
он будет использовать значение после последнего разделителя, который является просто пустой строкой. Поэтому лучше избегать косой черты, если вам нужно сделать такую вещь, как я.
awk '{$NF=""; print $0}' FS=: OFS=:
часто работает достаточно хорошо.
Предполагая довольно простое использование (без экранирования, например), вы можете использовать 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 (версия> = 3.2):
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e
Просто переведите разделитель на новую строку и выберите последнюю запись с помощью tail -1
.
\n
, но в большинстве случаев это наиболее читаемое решение.
Использование 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
Если ваше последнее поле состоит из одного символа, вы можете сделать это:
a="1:2:3:4:5"
echo ${a: -1}
echo ${a:(-1)}
Проверьте манипуляции со строками в bash .
a
, а не последнего поля .
Здесь есть много хороших ответов, но все же я хочу поделиться этим, используя базовое имя :
basename $(echo "a:b:c:d:e" | tr ':' '/')
Однако он потерпит неудачу, если в вашей строке уже есть «/» . Если косая черта / является вашим разделителем, то вам просто нужно (и нужно) использовать базовое имя.
Это не лучший ответ, но он просто показывает, как вы можете быть креативными, используя команды bash.
Используя Bash.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo \$${#}
0
echo ${!#}
вместо eval echo \$${#}
.
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, который будет применен к вводу.
Может быть, немного поздно с ответом, хотя простое решение состоит в том, чтобы изменить порядок ввода строки. Это позволит вам всегда получать последний предмет независимо от его длины.
[chris@desktop bin]$ echo 1:2:3:4:5 | rev | cut -d: -f1
5
Важно отметить, однако, что при использовании этого метода и числах больше, чем 1 цифра (или больше, чем один символ в любых обстоятельствах), вам нужно будет выполнить еще одну команду 'rev' для конвейерного вывода.
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1
42
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1 | rev
24
Надеюсь, я могу помочь, ура
Если вам нравится python и у вас есть возможность установить пакет, вы можете использовать эту утилиту python .
# install pythonp
pythonp -m pip install pythonp
echo "1:2:3:4:5" | pythonp "l.split(':')[-1]"
5
echo "1:2:3:4:5" | python -c "import sys; print(list(sys.stdin)[0].split(':')[-1])"
pythonp
пакета - заставить вас делать то же самое, что и python -c
при меньшем наборе символов. Пожалуйста, посмотрите на README в репозитории.
Соответствие регулярному выражению в sed
является жадным (всегда идет к последнему вхождению), которое вы можете использовать в своих интересах здесь:
$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5
5
если строка1:2:3:4:5:
(при использовании строковых операторов выдает пустой результат). Это особенно удобно при разборе путей, которые могут содержать (или не содержать) завершающий/
символ.