ฉันจะลบข้อความทั้งหมดหลังจากตัวละครในทุบตีได้อย่างไร


147

ฉันจะลบข้อความทั้งหมดหลังจากตัวละครในกรณีนี้เครื่องหมายโคลอน (":") เป็นทุบตีได้อย่างไร ฉันสามารถนำโคลอนออกด้วยหรือไม่ ฉันไม่รู้จะทำยังไง

คำตอบ:


134

ตัวอย่างอาจมีประโยชน์ แต่ถ้าฉันเข้าใจคุณถูกต้องสิ่งนี้จะใช้ได้:

echo "Hello: world" | cut -f1 -d":"

สิ่งนี้จะแปลง "hello: world" เป็น "hello"


5
cutทำงานได้ แต่คำตอบของเดนนิสดีกว่าและยืดหยุ่นกว่า ไม่มีใครรู้ว่ามันจะวางกระบวนการใหม่เช่นนั้นcutหรือไม่?
JoBu1324

3
มันจะดีกว่าที่จะใช้คุณสมบัติการขยายพารามิเตอร์ในตัวของ Bash มากกว่าการสร้าง subshells ที่ใช้เครื่องมือเช่นbasenameและcutดูคำตอบของ Dennis ด้านล่าง
Louis Maddox

1
cutสามารถอ่านได้จาก stdin ดังนั้นจึงเป็นการดีกว่าโดยเฉพาะเมื่อคุณมีสตริงที่ยาวมากซึ่งคุณต้องดำเนินการเช่นเนื้อหาของไฟล์
Sahas

1
และสิ่งนี้จะถูกนำไปใช้hello: worldอย่างไร นี่คือคำตอบครึ่งหนึ่ง
K - ความเป็นพิษใน SO กำลังเพิ่มขึ้น

มันสามารถทำได้โดยใช้ไวยากรณ์การชดเชยเช่น {var /: / ''} แต่ใช้งานได้เฉพาะในทุบตี ..
Mahesh

264

ใน Bash (และ ksh, zsh, dash ฯลฯ ) คุณสามารถใช้การขยายพารามิเตอร์%ที่จะลบอักขระออกจากจุดสิ้นสุดของสตริงหรือ#ซึ่งจะลบอักขระจากจุดเริ่มต้นของสตริง หากคุณใช้หนึ่งในอักขระเหล่านั้นสตริงการจับคู่ที่เล็กที่สุดจะถูกลบออก หากคุณเพิ่มตัวละครเป็นสองเท่าตัวละครที่ยาวที่สุดจะถูกลบออก

$ a='hello:world'
$ b=${a%:*}
$ echo "$b"
hello
$ a='hello:world:of:tomorrow'
$ echo "${a%:*}"
hello:world:of
$ echo "${a%%:*}"
hello
$ echo "${a#*:}"
world:of:tomorrow
$ echo "${a##*:}"
tomorrow

6
นี่คือการจัดการสตริงเนทีฟเชลล์ดังนั้นจึงไม่มีกระบวนการเพิ่มเติมที่จะวางไข่ การอ้างอิงการแทนที่พารามิเตอร์ Bash , การจัดการสตริงของ Bashและการเขียนสคริปต์ Bash ที่ดีขึ้น
Dodzi Dzakuma

@denniswilliamson วิธีการได้ฉันลบ 2 ตัวอักษรหลังจากสตริงที่เฉพาะเจาะจงเช่นhello:worldจะกลายเป็นhello:woโดยใช้${a%:*}?
3kstc

คำตอบที่ดีขอบคุณมาก แต่มันก็ดีถ้าเพิ่ม"${a##*:}"เฉพาะการtomorrow= เท่านั้น
avtomaton

1
@openCivilisation: คุณอาจต้องใช้การจับคู่นิพจน์ทั่วไปตามด้วย: a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$'; [[$ a = ~ $ รูปแบบ]]; echo "$ {BASH_REMATCH [1]}" ` ที่ตรงกับถ้ามีลำไส้ใหญ่ หากคุณต้องการให้เป็นตัวเลือกรูปแบบอื่นจะต้องมีการใช้ คำอธิบายของ Bash regexes (และ regexes โดยทั่วไป) อยู่นอกเหนือขอบเขตของความคิดเห็นเหล่านี้ คุณสามารถค้นหาคำถามอื่น ๆ ที่พูดถึงเรื่องนี้หรือโพสต์ของคุณเอง
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

1
@ kp123: มันเป็นตัวอย่างแรกในคำตอบของฉัน ครั้งที่สองที่ฉันแสดง (ที่ "พรุ่งนี้" ถูกลบ) มันเกือบจะเป็นสถานการณ์ที่คุณถาม
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป


4
egrep -o '^[^:]*:'

คุณช่วยอธิบายวิธีตีความสิ่งนี้ได้ไหมขอบคุณ
rɑːdʒɑ

1
egrepเป็น grep -Eกับ grepมันทำให้ไม่แตกต่างจากที่นี่เป็นประจำ -oสั่งให้ grep พิมพ์เฉพาะส่วนของบรรทัดที่ตรงกับนิพจน์เท่านั้น ^ยึดการจับคู่กับจุดเริ่มต้นของบรรทัด [^:]*จับคู่อักขระศูนย์หรือมากกว่านั้นไม่ใช่:อักขระ ตรงกับตัวอักษร: :
cdhowie

ขอขอบคุณอีกครั้งสำหรับคำอธิบาย
2559

3

สมมติว่าคุณมีเส้นทางพร้อมไฟล์ในรูปแบบนี้:

/dirA/dirB/dirC/filename.file

ตอนนี้คุณต้องการเส้นทางที่มีสี่ "/" เท่านั้น ชนิด

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"

และผลลัพธ์ของคุณจะเป็น

/dirA/dirB/dirC

ข้อดีของการใช้การตัดคือคุณยังสามารถตัดออกไดเรกทอรีที่ดีที่สุดเช่นเดียวกับไฟล์ (ในตัวอย่างนี้) ดังนั้นหากคุณพิมพ์

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"

ผลลัพธ์ของคุณจะเป็น

/dirA/dirB

แม้ว่าคุณจะสามารถทำสิ่งเดียวกันจากอีกด้านหนึ่งของสตริงได้ แต่มันก็ไม่สมเหตุสมผลนักในกรณีนี้เมื่อพิมพ์

$ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"

ผลลัพธ์ใน

dirA/dirB/dirC

ในบางกรณีกรณีสุดท้ายอาจเป็นประโยชน์เช่นกัน โปรดทราบว่าไม่มี "/" ที่จุดเริ่มต้นของเอาต์พุตล่าสุด


2
จะเกิดอะไรขึ้นถ้าคุณมีไดเรกทอรี "/resources/views/admin/users/relationships/posts.blade.php" และคุณต้องการที่จะตัดทอนทุกสิ่งหลังจากการเกิด "/" ของ LAST หลังจากที่คุณไม่รู้จำนวน "/ "ตัวอักษรอยู่ในสตริง ดังนั้นที่นี่ฉันต้องการให้ผลลัพธ์เป็น "/ resources / views / admin / ผู้ใช้ / ความสัมพันธ์ /" (หรือแม้กระทั่ง / ทรัพยากร / อ่าน / admin / ผู้ใช้ / ความสัมพันธ์โดยไม่มีเครื่องหมายทับ) คุณจะทำอย่างไร
kp123

-1

ตัดทุกอย่างหลังจากอินสแตนซ์สุดท้ายของ ":"

cat fileListingPathsAndFiles.txt | grep -o '^.*:'

และถ้าคุณต้องการที่จะลดลงล่าสุด ":"

cat file.txt | grep -o '^.*:' | sed 's/:$//'

@ kp123: คุณต้องการแทนที่:ด้วย/(ซึ่งควรเป็นเครื่องหมายโคลอน\/)

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