Tôi có một biến var
trong tập lệnh Bash chứa một chuỗi, như:
echo $var
"some string.rtf"
Tôi muốn xóa 4 ký tự cuối của chuỗi này và gán kết quả cho một biến mới var2
, để
echo $var2
"some string"
Tôi có thể làm cái này như thế nào?
Tôi có một biến var
trong tập lệnh Bash chứa một chuỗi, như:
echo $var
"some string.rtf"
Tôi muốn xóa 4 ký tự cuối của chuỗi này và gán kết quả cho một biến mới var2
, để
echo $var2
"some string"
Tôi có thể làm cái này như thế nào?
Câu trả lời:
Đầu tiên, bạn nên rõ ràng về những gì bạn muốn. Nếu bạn biết chuỗi kết thúc .rtf
và bạn muốn loại bỏ .rtf
, bạn có thể sử dụng var2=${var%.rtf}
. Nếu bạn không biết hậu tố là gì nhưng bạn muốn xóa mọi thứ bắt đầu bằng cái cuối cùng .
, thì bạn có thể sử dụng var2=${var%.*}
. Nếu bạn chỉ muốn giữ mọi thứ cho đến đầu tiên .
, bạn có thể sử dụng var2=${var%%.*}
. Hai tùy chọn cuối cùng có cùng kết quả nếu chỉ có một khoảng thời gian, nhưng nếu có thể có nhiều hơn một, bạn nên quyết định xem bạn muốn gì.
Nếu bạn thực sự muốn luôn loại bỏ một số lượng ký tự chính xác, đây là một số tùy chọn.
Bạn đã chỉ định bash cụ thể, vì vậy chúng tôi sẽ bắt đầu với các nội dung bash. Cái đã làm việc lâu nhất là cú pháp loại bỏ hậu tố giống như tôi đã sử dụng ở trên: để loại bỏ bốn ký tự, sử dụng var2=${var%????}
. Bạn cần xóa một dấu hỏi cho mỗi ký tự, vì vậy điều này trở nên khó sử dụng cho độ dài chuỗi con lớn hơn.
Hơi mới hơn là trích xuất chuỗi con : var2=${var::${#var}-4}
. Tại đây bạn có thể đặt bất kỳ số nào thay thế 4
cho một số ký tự khác nhau. ( ${#var}
Được thay thế bằng độ dài của chuỗi, vì vậy đây thực sự là yêu cầu giữ các ký tự (độ dài - 4) đầu tiên.)
Các phiên bản mới hơn của bash (cụ thể là 4+, có nghĩa là phiên bản được phát hành với MacOS sẽ không hoạt động) cho phép bạn đơn giản hóa điều đó var2=${var::-4}
.
Nếu bạn không thực sự sử dụng bash nhưng một số loại vỏ POSIX khác, việc loại bỏ hậu tố sẽ vẫn hoạt động, ngay cả trong dấu gạch ngang cũ (nơi không có phần còn lại sẽ). Trong zsh, tất cả đều hoạt động nhưng bạn phải đặt một 0
dấu hai chấm: var2=${var:0:-4}
v.v ... Trong ksh, bạn cần 0 và cũng phải sử dụng biểu thức length-4 rõ ràng : var2=${var:0:${#var}-4}
.
Tất nhiên bạn có thể sử dụng thay thế lệnh để làm điều đó với sự trợ giúp của một chương trình tiện ích; có rất nhiều thứ sẽ hoạt động, nhưng một cái gì đó giống như var2=$(cut -c -4 <<<"$var")
có lẽ là lựa chọn ngắn nhất.
Bạn có thể làm như thế này:
#!/bin/bash
v="some string.rtf"
v2=${v::-4}
echo "$v --> $v2"
bash
4+, nhưng trong phiên bản trước, bạn có thể sử dụng lâu hơn một chút ${v::${#v}-4}
.
${v::-4}
croaks "zsh: đóng cú đúp dự kiến". Nhưng câu trả lời của @fredtantini dưới đây ${v:0:-4}
hoạt động tốt.
Để loại bỏ bốn ký tự từ cuối chuỗi sử dụng ${var%????}
.
Để loại bỏ mọi thứ sau khi .
sử dụng cuối cùng ${var%.*}
.
${var#????}
cho điều đó.
Những gì làm việc cho tôi là:
echo "hello world" | rev | cut -c5- | rev
# hello w
Nhưng tôi đã sử dụng nó để cắt các dòng trong một tập tin vì vậy đó là lý do tại sao nó trông khó xử. Công dụng thực sự là:
cat somefile | rev | cut -c5- | rev
cut
chỉ đưa bạn đến mức cắt tỉa từ một số vị trí bắt đầu, điều này là xấu nếu bạn cần các hàng có chiều dài thay đổi. Vì vậy, giải pháp này đảo ngược ( rev
) chuỗi và bây giờ chúng ta liên quan đến vị trí kết thúc của nó, sau đó sử dụng cut
như đã đề cập và đảo ngược (một lần nữa rev
), trở lại trật tự ban đầu.
rev
đảo ngược dòng, không phải chuỗi. echo $SOME_VAR | rev | ...
có lẽ sẽ không hành xử như người ta mong đợi
Sử dụng Mở rộng biến / Thay thế chuỗi con :
$ {var /% Mẫu / Thay thế}
Nếu hậu tố của var khớp với Mẫu, thì thay thế Thay thế cho Mẫu.
Vì vậy, bạn có thể làm:
~$ echo ${var/%????/}
some string
Ngoài ra,
Nếu bạn luôn có 4 chữ cái giống nhau
~$ echo ${var/.rtf/}
some string
Nếu nó luôn kết thúc bằng .xyz
:
~$ echo ${var%.*}
some string
Bạn cũng có thể sử dụng độ dài của chuỗi:
~$ len=${#var}
~$ echo ${var::len-4}
some string
hoặc đơn giản echo ${var::-4}
len=${#var}; echo ${var::len-4}
có thể rút ngắn thành echo ${var:0:-4}
:-) EDIT: hoặc như @iyonizer đã chỉ ra, chỉ cần echo ${var::-4}
...
Bạn có thể sử dụng sed,
sed 's/.\{4\}$//' <<< "$var"
Thí dụ:
$ var="some string.rtf"
$ var1=$(sed 's/.\{4\}$//' <<< "$var")
$ echo $var1
some string
var2
?
Tôi đã thử những điều sau đây và nó đã làm việc cho tôi:
#! /bin/bash
var="hello.c"
length=${#var}
endindex=$(expr $length - 4)
echo ${var:0:$endindex}
Đầu ra: hel
Hy vọng ví dụ dưới đây sẽ giúp ích,
echo ${name:0:$((${#name}-10))}
-> ${name:start:len}
start
là điểm bắt đầu của chuỗilen
là độ dài của chuỗi phải được loại bỏ.Thí dụ:
read -p "Enter:" name
echo ${name:0:$((${#name}-10))}
Đầu ra:
Enter:Siddharth Murugan
Siddhar
Lưu ý: Bash 4.2 đã thêm hỗ trợ cho chuỗi con âm
Trong trường hợp này, bạn có thể sử dụng tên cơ sở giả sử bạn có cùng hậu tố trên các tệp bạn muốn xóa.
Thí dụ:
basename -s .rtf "some string.rtf"
Điều này sẽ trả về "một số chuỗi"
Nếu bạn không biết hậu tố và muốn xóa mọi thứ sau và kể cả dấu chấm cuối cùng:
f=file.whateverthisis
basename "${f%.*}"
đầu ra "tập tin"
% có nghĩa là chặt ,. là những gì bạn đang cắt, * là ký tự đại diện