Bash xóa các ký tự đầu tiên và cuối cùng khỏi một chuỗi


99

Tôi có một chuỗi như thế:

|abcdefg|

Và tôi muốn có được một chuỗi mới được gọi bằng cách nào đó (như chuỗi2) với chuỗi gốc không có hai |ký tự ở đầu và ở cuối chuỗi để tôi sẽ có chuỗi này:

abcdefg

Điều đó có thể trong bash không?

Câu trả lời:


121

Bạn có thể làm

string="|abcdefg|"
string2=${string#"|"}
string2=${string2%"|"}
echo $string2

Hoặc nếu độ dài chuỗi của bạn không đổi, bạn có thể làm

string="|abcdefg|"
string2=${string:1:7}
echo $string2

Ngoài ra, điều này sẽ làm việc

echo "|abcdefg|" | cut -d "|" -f 2

Ngoài ra cái này

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'

2
và cũngawk -F\| '{ print $2 }' <<<"|string|"
enzotib

1
@enzotib Bạn luôn có awkgiải pháp tuyệt vời . Tôi cần học hỏi awk.
Kris Harper

3
và cũng IFS='|' read string2 <<< $string:)
sắp xếp

10
và ngoài ra, trong bash 4.2 và mới hơn,"${string:1:-1}"
geirha

Đọc trong phần "mở rộng tham số" trong man bash.
Nemo

62

Đây là một giải pháp độc lập với độ dài của chuỗi (bash):

string="|abcdefg|"
echo "${string:1:${#string}-2}"

29

Tắt một vài bài viết được liệt kê ở đây có vẻ như cách đơn giản nhất để làm điều đó là:

string="|abcdefg|"
echo ${string:1:-1}

chỉnh sửa: hoạt động trên Ubuntu với bash 4.2; không hoạt động trên centOS với bash 4.1


20

Một cách khác là sử dụng head& taillệnh:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg

1
Tôi đã có một chuỗi [something something]với một mục tiêu để cắt ngoặc, vì vậy echo "[something something]" | tail -c +2 | head -c -2đã làm việc ra. Cảm ơn vì một lời khuyên!
Ain Tohvri

Rõ ràng, nó nên được echo -n "|abcdefg|" | tail -c +2 | head -c -1. Tôi không chắc tại sao các chỉnh sửa của mình bị từ chối ... Thật đáng buồn, thành thật mà nói. Xem man headđể biết thêm thông tin
Dmitry Khamitov


9

Bạn cũng có thể sử dụng sed để loại bỏ | không chỉ tham chiếu biểu tượng mà còn sử dụng các tham chiếu vị trí như trong:

$ echo "|abcdefg|" | sed 's:^.\(.*\).$:\1:'
abcdefg

Trong đó ':' là các dấu phân cách (bạn có thể thay thế chúng bằng / hoặc bất kỳ ký tự nào không có trong truy vấn, bất kỳ dấu hiệu nào sau s sẽ làm điều đó) Ở đây ^ (caret) có nghĩa là ở đầu chuỗi đầu vào và $ (đô la) có nghĩa là cuối cùng. Các . (điểm) rằng nó nằm sau dấu mũ và cái trước ký hiệu đô la đại diện cho một ký tự. Vì vậy, nói cách khác, chúng tôi đang xóa các ký tự đầu tiên và cuối cùng. Hãy nhớ rằng điều này sẽ xóa bất kỳ ký tự ngay cả khi | nó không có trong chuỗi.

VÍ DỤ:

$ echo "abcdefg" | sed 's:^.\(.*\).$:\1:'
bcdef

3

chức năng vỏ

Một cách tiếp cận dài dòng hơn một chút, nhưng hoạt động trên bất kỳ loại ký tự đầu tiên và cuối cùng, không nhất thiết phải giống nhau. Ý tưởng cơ bản là chúng ta đang lấy một biến, đọc ký tự theo từng ký tự và chỉ nối thêm những biến chúng ta muốn vào một biến mới

Đây là toàn bộ ý tưởng được định dạng thành một chức năng tốt

crop_string_ends() {
    STR="$1" 
    NEWSTR="" 
    COUNT=0 
    while read -n 1 CHAR 
    do
        COUNT=$(($COUNT+1)) 
        if [ $COUNT -eq 1 ] || [ $COUNT -eq ${#STR} ] 
        then
            continue 
        fi 
        NEWSTR="$NEWSTR"$CHAR 
    done <<<"$STR" 
    echo $NEWSTR 
}

Và đây là chức năng tương tự trong hành động:

$> crop_string_ends "|abcdefg|"                                                                                       
abcdefg
$> crop_string_ends "HelloWorld"                                                                                      
elloWorl

Con trăn

>>> mystring="|abcdefg|"
>>> print(mystring[1:-1])
abcdefg

hoặc trên dòng lệnh:

$ python -c 'import sys;print sys.stdin.read()[1:-2]' <<< "|abcdefg|"                                             
abcdefg

AWK

$ echo "|abcdefg|" | awk '{print substr($0,2,length($0)-2)}'                                                      
abcdefg

Hồng ngọc

$ ruby -ne 'print $_.split("|")[1]' <<< "|abcdefg|"                                                               
abcdefg

2

Giải pháp nhỏ và phổ quát:

expr "|abcdef|" : '.\(.*\).'

Đặc biệt trong trường hợp này và cho phép '|' nhân vật có thể ở đó hoặc không:

expr "|abcdef" : '|*\([^|]*\)|*'

2
$ string="|abcdefg|"
$ string="${string#?}" && string="${string%%?}"
$ echo "$string"
abcdefg

Từ http://tldp.org/LDP/abs/html/parameter-substlation.html

${var#Pattern}
Di chuyển từ $varcác ngắn nhất một phần của $Patternđiều đó phù hợp với kết thúc trước của $var. Xoá khỏi sự dài nhất là một phần của điều đó phù hợp với back-end của .
${var%%Pattern}
$var$Pattern$var

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.