Odpowiedzi:
Możesz użyć operatorów łańcuchowych :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
To łapczywie przycina wszystko od przodu do „:”.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
${foo%:*}
. #
- od początku; %
- od końca. #
, %
- najkrótszy mecz; ##
, %%
- najdłuższy mecz.
echo ${pwd##*/}
nie działa.
pwd
jako zmienną. Spróbować dir=$(pwd); echo ${dir##*/}
. Pracuje dla mnie!
Innym sposobem jest odwrócenie przed i po cut
:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
Ułatwia to uzyskanie przedostatniego pola lub dowolnego zakresu pól ponumerowanych od końca.
echo "1 2 3 4" | rev | cut -d " " -f1 | rev
rev
, właśnie tego potrzebowałem! cut -b20- | rev | cut -b10- | rev
Trudno jest uzyskać ostatnie pole za pomocą cut, ale oto kilka rozwiązań w awk i perl
echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
/
znak końcowy lub nie : /a/b/c/d
i /a/b/c/d/
daje ten sam wynik ( d
) podczas przetwarzania pwd | awk -F/ '{print $NF}'
. Przyjęta odpowiedź powoduje, że wynik jest pusty w przypadku/a/b/c/d/
/
jako separatora, a jeśli twoja ścieżka jest /my/path/dir/
, użyje wartości po ostatnim separatorze, który jest po prostu pustym ciągiem. Więc najlepiej unikać końcowego slashowania, jeśli musisz zrobić coś takiego jak ja.
awk '{$NF=""; print $0}' FS=: OFS=:
często działa wystarczająco dobrze.
Zakładając dość proste użycie (na przykład bez ucieczki z separatora), możesz użyć grep:
$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5
Podział - znajdź wszystkie znaki nie ogranicznik ([^:]) na końcu wiersza ($). -o drukuje tylko pasującą część.
Jednokierunkowa:
var1="1:2:3:4:5"
var2=${var1##*:}
Inny, używając tablicy:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}
Jeszcze inny z tablicą:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}
Używanie wyrażeń regularnych Bash (wersja> = 3.2):
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e
Po prostu przetłumacz ogranicznik na nowy wiersz i wybierz ostatni wpis za pomocą tail -1
.
\n
, ale w większości przypadków jest to najbardziej czytelne rozwiązanie.
Używanie 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
Jeśli twoje ostatnie pole to pojedynczy znak, możesz to zrobić:
a="1:2:3:4:5"
echo ${a: -1}
echo ${a:(-1)}
Sprawdź manipulację ciągiem w bash .
a
, nie ostatni pola .
Tutaj jest wiele dobrych odpowiedzi, ale nadal chcę udostępnić tę za pomocą basename :
basename $(echo "a:b:c:d:e" | tr ':' '/')
Jednak nie powiedzie się, jeśli w ciągu jest już trochę „/” . Jeśli slash / jest twoim ogranicznikiem, musisz (i powinieneś) użyć basename.
To nie jest najlepsza odpowiedź, ale pokazuje tylko, jak możesz być kreatywny za pomocą poleceń bash.
Korzystanie z Bash.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo \$${#}
0
echo ${!#}
zamiast eval echo \$${#}
.
for x in `echo $str | tr ";" "\n"`; do echo $x; done
Dla tych, którzy dobrze znają Python, https://github.com/Russell91/pythonpy to dobry wybór, aby rozwiązać ten problem.
$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'
Z pomocą pythonpy: -x treat each row of stdin as x
.
Za pomocą tego narzędzia łatwo jest napisać kod Pythona, który zostanie zastosowany do danych wejściowych.
Odpowiedź może być nieco spóźniona, chociaż prostym rozwiązaniem jest odwrócenie kolejności ciągu wejściowego. To pozwoli ci zawsze zdobyć ostatni przedmiot bez względu na długość.
[chris@desktop bin]$ echo 1:2:3:4:5 | rev | cut -d: -f1
5
Należy jednak pamiętać, że jeśli używasz tej metody, a liczby są większe niż 1 cyfra (lub w każdym przypadku większe niż jeden znak), będziesz musiał uruchomić inną komendę „rev” na wyjściu potokowym.
[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
Mam nadzieję, że mogę pomóc, na zdrowie
Jeśli podoba Ci się Python i masz opcję instalacji pakietu, możesz użyć tego narzędzia 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
pakietu jest zrobienie tego samego, co python -c
przy mniejszej liczbie znaków. Proszę spojrzeć na README w repozytorium.
5
jeśli ciąg jest1:2:3:4:5:
(podczas korzystania z operatorów ciąg daje pusty wynik). Jest to szczególnie przydatne podczas analizowania ścieżek, które mogą zawierać (lub nie) postać końcową/
.