ฉันจะได้รับสถานะการออกเมื่อใช้คำสั่ง sed ได้อย่างไร


11

grepคำสั่งให้ออกออกจากสถานะนี้:

$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1  

แต่ฉันต้องใช้sedและฉันรู้ว่ามันไม่มีสถานะการออก:

$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0  

ฉันรู้ว่าฉันควรเล่นด้วย-qตัวเลือก แต่ฉันไม่ประสบความสำเร็จ


7
โปรดทราบว่าsedส่วนใหญ่จะมีสถานะออก แต่ก็ไม่ได้ทำสิ่งที่คุณต้องการที่นี่ หากsedคำสั่งล้มเหลวตัวอย่างเช่นหากคุณพยายามเรียกใช้บนไฟล์ที่คุณไม่มีสิทธิ์เข้าถึงเพื่อเขียนหรือที่ไม่มีอยู่sedจะออกจากสถานะการออกที่ไม่ใช่ 0 สถานะการออกเพียงระบุว่าsedมีการจัดการที่จะทำในสิ่งที่คุณบอกให้ทำและecho "foo.bar" | sed 's/pop.*$//'ดำเนินการอย่างถูกต้อง popมันลบทุกบรรทัดด้วย ว่าไม่มีบรรทัดดังกล่าวไม่เกี่ยวข้องคำสั่งยังคงทำงาน
terdon

@ ซานาฉันกำลังจะโพสต์คำตอบ แต่ฉันรู้สึกว่านี่ไม่ได้ตอบคำถาม มันอธิบายความเข้าใจผิดเพียงอย่างเดียว แต่ไม่ได้ให้วิธีแก้ปัญหาที่เป็นประโยชน์เช่น steeldriver มีด้านล่าง ดังนั้นความคิดเห็นจึงดูเหมาะสมกว่า
terdon

คำตอบ:


13

คุณสามารถใช้ Q nที่จะเลิกกับสถานะทางออกn - แต่ที่จะทำให้มันมีประโยชน์นอกจากนี้คุณยังจะต้องใช้บางกิ่งและการควบคุมการไหล :

t
branch ตามเงื่อนไข (นั่นคือ: ข้ามไปที่เลเบล) เฉพาะเมื่อs/// คำสั่งประสบความสำเร็จตั้งแต่บรรทัดอินพุตสุดท้ายถูกอ่านหรือมีสาขาอื่นที่มีเงื่อนไข

อาจเป็นการดีที่สุดที่จะเลือกค่าสำหรับnที่แตกต่างจากหนึ่งในค่าสถานะการออกมาตรฐาน:

สถานะการออกเป็นศูนย์หมายถึงความสำเร็จและค่าที่ไม่ใช่ศูนย์หมายถึงความล้มเหลว GNU 'sed' ส่งคืนค่าข้อผิดพลาดสถานะ exit ต่อไปนี้:

0
 Successful completion.

1
 Invalid command, invalid syntax, invalid regular expression or a
 GNU 'sed' extension command used with '--posix'.

2
 One or more of the input file specified on the command line could
 not be opened (e.g.  if a file is not found, or read permission is
 denied).  Processing continued with other files.

4
 An I/O error, or a serious processing error during runtime, GNU
 'sed' aborted immediately.

ตัวอย่างเช่น

$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $? 
foo.
0

แต่ทว่า

$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $? 
foo.bar
42

หากคุณต้องการละเว้นการพิมพ์เริ่มต้นของพื้นที่รูปแบบจากนั้นแทนที่qด้วยQ(โปรดทราบว่าQเป็นส่วนขยาย GNU)


1

ต่อไปนี้เป็นวิธีค้นหา regex ด้วย sed และไฮไลต์การจับคู่หรือส่งคืนรหัสทางออก (5) หากไม่พบที่ตรงกัน:

นี่คือ input.txt:

hello there
my dear old friend
a lot of things
we'll pass along the end

นี่คือฟังก์ชั่นของฉันในการพิมพ์ทั้งหมด + ไฮไลต์การแข่งขัน + รหัสออกกลับ:

highlight()
{
  pattern=$1
  shift
  sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}

$ ไฮไลต์ "lo \ | end" input.txt || echo -e "\ n * ไม่พบการแข่งขัน *"

Hel ดูเถิดมี
ศุกร์เก่าของฉันรักจบดูเถิดตันของสิ่งที่ เราจะผ่านดูเถิด ng สิ้น

เมื่อไม่มีการจับคู่มันจะส่งคืนรหัสทางออก (5) คุณสามารถใช้กับ cat และ pipe | เช่นกัน:

$ cat input.txt | ไฮไลต์ "hot \ | และ" || echo -e "\ n * ไม่พบการแข่งขัน *"

สวัสดี
เพื่อนเก่าที่รักของฉัน
มีหลายสิ่งหลายอย่างที่
เราจะผ่านไปในตอนท้าย

* ไม่พบที่ตรงกัน *

ขอบคุณhttps://unix.stackexchange.com/a/405725/43233 - ฉันใช้มัน + ตัวเลือกการเลิกเล่น

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