ฉันจะตัดอักขระ X ตัวแรกออกจากสตริงโดยใช้ sed ได้อย่างไร


126

ฉันกำลังเขียนเชลล์สคริปต์สำหรับลินุกซ์แบบฝังในกล่องอุตสาหกรรมขนาดเล็ก ฉันมีตัวแปรที่มีข้อความpid: 1234และฉันต้องการตัดอักขระ X ตัวแรกออกจากบรรทัดดังนั้นจะมีเพียง 1234 ตัวเท่านั้น ฉันมีตัวแปรเพิ่มเติมที่ต้อง "ล้าง" ดังนั้นฉันจึงต้องตัด X อักขระแรกออกไปและใช้${string:5}ไม่ได้ด้วยเหตุผลบางประการในระบบของฉัน

sedสิ่งเดียวที่กล่องดูเหมือนว่าจะมีคือ

ฉันพยายามทำให้สิ่งต่อไปนี้ใช้งานได้:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

ความคิดใด ๆ ?


10
หาก${string:5}ไม่ได้ผลแสดงว่าคุณไม่ได้ใช้ Bash หรือเชลล์อื่นที่รองรับไวยากรณ์นั้น คุณใช้เชลล์และเวอร์ชันอะไร Shebang ของคุณมีลักษณะอย่างไร? ฉันเดาว่าคุณกำลังใช้sh(เช่นdash) หรืออาจเป็นไปzshได้
หยุดชั่วคราวจนกว่าจะมีประกาศอีกครั้ง

คำตอบ:


-1

สิ่งนี้จะได้ผลเช่นกัน:

echo "$pid"|awk '{print $2}'

27
คำถามนี้เป็นคำถามแรกสำหรับ "ข้ามอักขระ N ตัวแรกในสตริง" คุณไม่ได้ตอบคำถาม
jww

ดูเหมือนจะไม่ได้ผลและถ้าเป็นเช่นนั้นคุณช่วยอธิบายได้อย่างไร
Alexander Mills

มันทำงานบนระบบของฉัน awk -F": " '{print $2}'อาจจะมีปัญหากับการแยกข้อมูลของคุณลอง ยังไม่ใช่วิธีแก้ปัญหาที่ฉันชอบ
mzuther

197

สิ่งต่อไปนี้ควรใช้งานได้:

var="pid: 1234"
var=${var:5}

คุณแน่ใจหรือไม่ว่าbashเชลล์เรียกใช้สคริปต์ของคุณ

แม้แต่ตามมาตรฐาน POSIX

var=${var#?????}

จะดีกว่าการใช้กระบวนการภายนอกแม้ว่าสิ่งนี้จะทำให้คุณต้องฮาร์ดโค้ด 5 ในรูปแบบความยาวคงที่


1
นอกจากนี้คุณยังสามารถระบุความยาวที่มีพารามิเตอร์ที่สอง: ${var:5:2}จะเริ่มต้นที่และผลตอบแทน1 12
Max Candocia

109

นี่คือวิธีการที่รัดกุมในการตัดตัวอักษร X cut(1)ครั้งแรกที่ใช้ ตัวอย่างนี้ลบอักขระ 4 ตัวแรกโดยการตัดสตริงย่อยที่เริ่มต้นด้วยอักขระที่ 5

echo "$pid" | cut -c 5-

2
นี่คือทางออกที่ง่ายที่สุด!
Brandon

2
ในทางเทคนิค OP ขอ sed แต่ฉันรู้สึกว่านี่เป็นทางออกที่ดีที่สุดสำหรับ "ฉันจะดึงอักขระ X ตัวแรกออกจากสตริง [ในเทอร์มินัล / bash] ได้อย่างไร" เมื่อใช้ร่วมกับคอมไพล์มันก็ดี:git log --pretty=oneline | cut -c 42- | head
นักแม่นปืน

1
+1 วิธีแก้ปัญหาที่ง่ายและเป็นประโยชน์ .. เมื่อฉันมี URL เป็น http: // <example.com> และเพื่อตัดโปรโตคอล "http: //" ฉันต้องพูดเป็น 8 ตัวอักษรแทนที่จะเป็น 7 ฉันไม่รู้ แต่นั่นเป็นวิธีที่ได้ผลสำหรับฉัน
Santosh Kumar Arjunan

1
Santosh Kumar Arjunan: นั่นเป็นเพราะตัวอย่าง "echo" $ pid "| cut -c 4-" นั้นแท้จริงแล้วไม่ได้ตัดอักขระ 4 ตัวแรก แต่แยกสตริงย่อยโดยเริ่มจากอักขระที่ 4 ดังนั้นจึงตัดอักขระ 3 ตัวแรกออกไป ดังนั้นหากคุณต้องการตัดอักขระแรก 7 ตัวคุณต้องการแยกทุกอย่างออกจากอักขระที่ 8 ดังนั้นจึงต้องทำ "cut -c 8-"
al-ash

1
@DeanHiller cut -c ${LEN}-. วงเล็บปีกกาใช้เพื่อเชื่อมสตริงเข้ากับอักขระตัวแปรที่ถูกต้องเพื่อแยกแยะว่าอะไรคือตัวแปรและอะไรที่ไม่ใช่ หากคุณต้องการข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้ให้ค้นหา "bash variable string concatenation" เพื่อดูแหล่งข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุ / วิธีการทำงาน
JustCarty

46

ใช้-rตัวเลือก ("ใช้นิพจน์ทั่วไปที่ขยายในสคริปต์") ถึงsedเพื่อใช้{n}ไวยากรณ์:

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234

1
ในกรณีนี้จะเป็นอย่างไรถ้าฉันต้องการตัดอักขระ X สุดท้ายออกจากสตริง
Kokesh

5
@Kokesh: คุณสามารถsed -r 's/.{5}$//'ตัดอักขระ 5 ตัวสุดท้ายแทนได้
Mark Longair

7
คุณสามารถทำได้โดยไม่ต้องใช้-r( -Eใน OS X, IIRC) หากคุณหลุดเครื่องหมายวงเล็บ (ไม่รู้ว่าใช้ได้กับ OS X หรือไม่)
หยุดชั่วคราวจนกว่าจะมีประกาศอีกครั้ง

2
@ เดนนิส: ฉันเพิ่งตรวจสอบ - การออกจากวงเล็บปีกกา (และออก-r/ -E) ใช้งานได้ใน OS X
Gordon Davisson

16

ตัดอักขระสองตัวแรกออกจากสตริง:

$ string="1234567890"; echo "${string:2}"
34567890

@ dtp70 ขอบคุณมากสำหรับคำตอบทั่วไปมันใช้งานได้ดี!
wolfram77

10

ไปป์ผ่านโดยawk '{print substr($0,42)}'ที่ 42 เป็นมากกว่าจำนวนอักขระที่จะดรอป ตัวอย่างเช่น:

$ echo abcde| awk '{print substr($0,2)}'
bcde
$

8

โอกาสที่คุณจะมีcutเช่นกัน ถ้าเป็นเช่นนั้น:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234

1
ปัญหาcutคือมันไม่จัดการลำดับของช่องว่างอย่างสมเหตุสมผลการใช้tr -s ' 'การ "บีบ" ช่องว่างทำให้ทำงานได้ดีขึ้น

1
มันไม่ได้หมายความว่าจะเป็นเครื่องมือเต้นทั้งหมดที่ร้องเพลงทั้งหมด มันง่ายและทำตามที่ระบุไว้ในกระป๋องและมีให้บริการอย่างกว้างขวาง ควรใช้งานได้ดีสำหรับข้อกำหนดดังกล่าวและแน่นอนว่าจะมีประสิทธิภาพมากขึ้นในการครอบตัดอักขระคงที่ออกจากตำแหน่งเฉพาะ
Shawn Chin

5

ดีมีได้รับการแก้ปัญหาที่นี่กับsed, awk, cutและการใช้bashไวยากรณ์ ฉันแค่ต้องการเปลี่ยนรูปแบบที่สอดคล้องกับ POSIX อื่น:

$ echo "pid: 1234" | tail -c +6
1234

-cบอกหางที่จะเริ่มต้นออฟเซ็ตไบต์โดยนับจากจุดสิ้นสุดของข้อมูลอินพุต แต่ถ้าตัวเลขขึ้นต้นด้วย+เครื่องหมายแสดงว่านับจากจุดเริ่มต้นของข้อมูลอินพุตไปจนถึงจุดสิ้นสุด


4

อีกวิธีหนึ่งโดยใช้cutแทนsed.

result=`echo $pid | cut -c 5-`

เขาต้องการลบอักขระ 4 ตัวแรกออก สิ่งนี้ได้รับ 4 อักขระแรก
มม.

2

ผมพบคำตอบในบริสุทธิ์ sed จัดทำโดยคำถามนี้ (เป็นที่ยอมรับโพสต์หลังจากที่คำถามนี้ถูกโพสต์) สิ่งนี้ทำตามที่คุณถาม แต่เพียงผู้เดียวใน sed:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

จุดในsed '/./) คือสิ่งที่คุณต้องการจับคู่ คำถามของคุณคือสิ่งที่ฉันพยายามทำยกเว้นในกรณีของฉันฉันต้องการจับคู่บรรทัดเฉพาะในไฟล์แล้วจึงไม่ใส่ความคิดเห็น ในกรณีของฉันมันคือ:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

-iหลังsedคือการแก้ไขไฟล์ในสถานที่ (ถอดสวิตช์นี้ถ้าคุณต้องการที่จะทดสอบการแสดงออกจับคู่ของคุณก่อนที่จะมีการแก้ไขไฟล์)

(ฉันโพสต์สิ่งนี้เพราะฉันต้องการทำสิ่งนี้โดยสิ้นเชิงตามที่คำถามนี้ถามและไม่มีคำตอบก่อนหน้านี้ที่ช่วยแก้ปัญหานั้นได้)


1

แทนที่จะลบอักขระ n ตัวออกจากจุดเริ่มต้นบางทีคุณอาจดึงตัวเลขออกมาโดยตรง ชอบจัง ...

$ echo "pid: 1234" | grep -Po "\d+"

นี่อาจเป็นโซลูชันที่มีประสิทธิภาพมากกว่าและดูเหมือนจะใช้งานง่ายกว่า

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