Bash ลบอักขระตัวแรกและตัวสุดท้ายออกจากสตริง


98

ฉันมีสตริงเช่นนั้น:

|abcdefg|

และฉันต้องการรับสายอักขระใหม่ที่เรียกว่า Someway (เช่น string2) ด้วยสายอักขระดั้งเดิมโดยไม่มี|อักขระสองตัวที่เริ่มต้นและท้ายสุดเพื่อให้ฉันมี:

abcdefg

เป็นไปได้ในการทุบตี?

คำตอบ:


120

คุณทำได้

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

หรือถ้าความยาวสตริงของคุณคงที่คุณสามารถทำได้

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

นอกจากนี้ควรทำงาน

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

นอกจากนี้ยัง

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

2
และยังawk -F\| '{ print $2 }' <<<"|string|"
enzotib

1
@enzotib คุณมีawkทางออกที่ยอดเยี่ยมเสมอ awkฉันต้องการที่จะเรียนรู้
Kris Harper

3
และยังIFS='|' read string2 <<< $string:)
จัด

10
และใน bash 4.2 และที่ใหม่กว่านั้น"${string:1:-1}"
geirha

อ่านภายใต้ "การขยายตัวพารามิเตอร์" man bashในหัวข้อ
Nemo

62

นี่คือวิธีแก้ปัญหาที่ไม่ขึ้นกับความยาวของสตริง (bash):

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

29

การโพสต์บางรายการไว้ที่นี่ดูเหมือนว่าวิธีที่ง่ายที่สุดคือ:

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

แก้ไข: ทำงานบน Ubuntu กับทุบตี 4.2; ไม่ทำงานบน centOS ด้วย bash 4.1


19

อีกวิธีหนึ่งคือการใช้head& tailคำสั่ง:

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

1
ฉันมี[something something]เป้าหมายเพื่อตัดวงเล็บดังนั้นจึงเป็นecho "[something something]" | tail -c +2 | head -c -2ไปได้ ขอบคุณสำหรับเคล็ดลับ!
Ain Tohvri

echo -n "|abcdefg|" | tail -c +2 | head -c -1เห็นได้ชัดว่ามันควรจะเป็น ฉันไม่แน่ใจว่าทำไมการแก้ไขของฉันถูกปฏิเสธ ... มันน่าเศร้ามากที่จะซื่อสัตย์ ดูman headข้อมูลเพิ่มเติม
Dmitry Khamitov


9

คุณยังสามารถใช้ sed เพื่อลบ | ไม่เพียงอ้างอิงสัญลักษณ์ แต่ใช้การอ้างอิงตำแหน่งใน:

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

โดยที่ ':' เป็นตัวคั่น (คุณสามารถแทนที่ด้วย / หรืออักขระใด ๆ ที่ไม่ได้อยู่ในแบบสอบถามเครื่องหมายใด ๆ ที่ตามมาจะทำ) ที่นี่ ^ (คาเร็ต) หมายถึงที่จุดเริ่มต้นของสตริงอินพุตและ $ (ดอลลาร์) หมายถึง ในตอนท้าย ส่วน (จุด) ว่ามันอยู่หลังเครื่องหมายรูปหมวกและตัวที่อยู่ก่อนเครื่องหมายดอลลาร์แสดงถึงอักขระตัวเดียว ดังนั้นในคำอื่น ๆ เราจะลบตัวอักษรแรกและตัวสุดท้าย โปรดทราบว่าการดำเนินการนี้จะลบอักขระใด ๆ แม้ว่า | ไม่มีอยู่ในสตริง

EX:

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

3

ฟังก์ชั่นเปลือก

วิธีการ verbose อีกเล็กน้อย แต่ทำงานในประเภทแรกและตัวละครสุดท้ายไม่จำเป็นต้องเหมือนกัน แนวคิดพื้นฐานคือเรากำลังรับตัวแปรอ่านตัวอักษรเป็นตัวอักษรและต่อท้ายเฉพาะที่เราต้องการให้เป็นตัวแปรใหม่

นี่คือแนวคิดทั้งหมดที่จัดรูปแบบเป็นฟังก์ชันที่ดี

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 
}

และนี่คือฟังก์ชั่นการทำงานเดียวกัน:

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

หลาม

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

หรือบนบรรทัดคำสั่ง:

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

AWK

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

ทับทิม

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

2

โซลูชันขนาดเล็กและสากล:

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

พิเศษในกรณีนี้และอนุญาตให้ '|' ตัวละครอาจอยู่ที่นั่นหรือไม่:

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

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

จากhttp://tldp.org/LDP/abs/html/parameter-substitution.html

${var#Pattern}
นำออกจากสั้นที่สุดส่วนหนึ่งของที่ตรงกับปลายด้านหน้าของ นำออกจากยาวที่สุดส่วนหนึ่งของที่ตรงกับปลายด้านหลังของ $var$Pattern$var
${var%%Pattern}
$var$Pattern$var

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.