Câu trả lời:
Bạn có thể sử dụng toán tử chuỗi :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
Điều này cắt mọi thứ từ phía trước cho đến khi ':', tham lam.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
${foo%:*}
. #
- từ lúc bắt đầu; %
- từ cuối. #
, %
- trận đấu ngắn nhất; ##
, %%
- trận đấu dài nhất.
echo ${pwd##*/}
không hoạt động.
pwd
như một biến. Hãy thử dir=$(pwd); echo ${dir##*/}
. Làm việc cho tôi!
Một cách khác là đảo ngược trước và sau cut
:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
Điều này làm cho nó rất dễ dàng để có được trường cuối cùng nhưng một trường hoặc bất kỳ phạm vi trường nào được đánh số từ cuối.
echo "1 2 3 4" | rev | cut -d " " -f1 | rev
rev
, chỉ là những gì tôi cần! cut -b20- | rev | cut -b10- | rev
Thật khó để có được trường cuối cùng bằng cách sử dụng cắt, nhưng đây là một số giải pháp trong awk và perl
echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
/
ký tự hoàn thiện : /a/b/c/d
và /a/b/c/d/
mang lại kết quả tương tự ( d
) khi xử lý pwd | awk -F/ '{print $NF}'
. Câu trả lời được chấp nhận dẫn đến một kết quả trống rỗng trong trường hợp/a/b/c/d/
/
làm dấu phân cách và nếu đường dẫn của bạn là /my/path/dir/
nó sẽ sử dụng giá trị sau dấu phân cách cuối cùng, đó đơn giản là một chuỗi rỗng. Vì vậy, tốt nhất là tránh dấu gạch chéo nếu bạn cần làm một việc như tôi.
awk '{$NF=""; print $0}' FS=: OFS=:
thường hoạt động đủ tốt.
Giả sử sử dụng khá đơn giản (chẳng hạn như không có dấu phân cách), bạn có thể sử dụng grep:
$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5
Phân tích - tìm tất cả các ký tự không phải là dấu phân cách ([^:]) ở cuối dòng ($). -o chỉ in phần phù hợp.
Một chiều:
var1="1:2:3:4:5"
var2=${var1##*:}
Khác, sử dụng một mảng:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}
Một cái khác với một mảng:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}
Sử dụng Bash (phiên bản> = 3.2) biểu thức chính quy:
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e
Đơn giản chỉ cần dịch dấu phân cách thành một dòng mới và chọn mục cuối cùng với tail -1
.
\n
, nhưng đối với hầu hết các trường hợp là giải pháp dễ đọc nhất.
Sử dụng 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
Nếu trường cuối cùng của bạn là một ký tự đơn, bạn có thể làm điều này:
a="1:2:3:4:5"
echo ${a: -1}
echo ${a:(-1)}
Kiểm tra thao tác chuỗi trong bash .
a
, không phải là cuối cùng lĩnh vực .
Có nhiều câu trả lời hay ở đây, nhưng tôi vẫn muốn chia sẻ câu hỏi này bằng tên cơ sở :
basename $(echo "a:b:c:d:e" | tr ':' '/')
Tuy nhiên, nó sẽ thất bại nếu đã có một số '/' trong chuỗi của bạn . Nếu dấu gạch chéo / là dấu phân cách của bạn thì bạn chỉ cần (và nên) sử dụng tên cơ sở.
Đây không phải là câu trả lời hay nhất nhưng nó chỉ cho thấy cách bạn có thể sáng tạo bằng cách sử dụng các lệnh bash.
Sử dụng Bash.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo \$${#}
0
echo ${!#}
thay vì eval echo \$${#}
.
for x in `echo $str | tr ";" "\n"`; do echo $x; done
Đối với những người thoải mái với Python, https://github.com/Russell91/pythonpy là một lựa chọn tốt để giải quyết vấn đề này.
$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'
Từ pythonpy giúp : -x treat each row of stdin as x
.
Với công cụ đó, thật dễ dàng để viết mã python được áp dụng cho đầu vào.
Có thể hơi muộn với câu trả lời mặc dù một giải pháp đơn giản là đảo ngược thứ tự của chuỗi đầu vào. Điều này sẽ cho phép bạn luôn đạt được mục cuối cùng bất kể chiều dài.
[chris@desktop bin]$ echo 1:2:3:4:5 | rev | cut -d: -f1
5
Tuy nhiên, điều quan trọng cần lưu ý là, nếu sử dụng phương pháp này và các số lớn hơn 1 chữ số (Hoặc lớn hơn một ký tự trong mọi trường hợp), bạn sẽ cần chạy lệnh 'rev' khác trên đầu ra đường ống.
[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
Hy vọng tôi có thể giúp đỡ, chúc mừng
Nếu bạn thích python và có một tùy chọn để cài đặt một gói, bạn có thể sử dụng tiện ích python này .
# 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
gói là để làm cho bạn làm những điều tương tự như python -c
với ít kiểu chữ ký tự hơn. Xin hãy xem README trong kho lưu trữ.
5
nếu chuỗi là1:2:3:4:5:
(trong khi sử dụng toán tử chuỗi mang lại kết quả trống). Điều này đặc biệt hữu ích khi phân tích cú pháp các đường dẫn có thể chứa (hoặc không) một/
ký tự hoàn thiện .