Відповіді:
Ви можете використовувати рядкові оператори :
$ 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
Останнє поле отримати важко за допомогою вирізання, але ось декілька рішень у 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=:
часто працює досить добре.
Якщо припустити досить просте використання (наприклад, не виходить роздільник, наприклад, ви можете використовувати греп:)
$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5
Розбивка - знайдіть усіх символів не роздільник ([^:]) в кінці рядка ($). -друкує лише відповідну частину.
Односторонній:
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)}
Перевірте маніпуляцію з рядком в баші .
a
, а не останньої поля .
Тут є багато хороших відповідей, але все ж я хочу поділитися цим за допомогою базового імені :
basename $(echo "a:b:c:d:e" | tr ':' '/')
Однак це не вдасться, якщо у вашому рядку вже є деякі '/' . Якщо slash / є вашим роздільником, ви просто повинні (і повинні) використовувати базове ім'я.
Це не найкраща відповідь, але вона просто показує, як можна бути творчим за допомогою команд 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, який застосовується до вводу.
Можливо, трохи запізнюється з відповіддю, хоча простим рішенням є змінити порядок введення рядка. Це дозволить вам завжди отримувати останній елемент незалежно від довжини.
[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 у сховищі.
Збіг Regex sed
- жадібний (завжди йде до останнього явища), який ви можете використати для себе на користь
$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5
5
якщо рядок є1:2:3:4:5:
(при використанні операторів рядків дає порожній результат). Це особливо зручно при аналізі контурів, які можуть містити (або не мати) фінішний/
символ.