เกี่ยวกับแบบพกพา sed -e ... db หรือ! ข?


12

ในการแก้ไข นี้Stéphane Chazelas POSIXify (อีกครั้ง)sedการจัดรูปแบบของฉันโดยการแทรกตัว-eแบ่ง xpression และ-eคำสั่ง xpression อื่น ตอนนี้ฉันอาจจะถามเขาว่าทำไมในความคิดเห็นฉันคิดว่า แต่มันก็มีการแก้ไขหมายเลข 18 ในคำตอบนั้นและเกือบทั้งหมดก่อนหน้านี้แล้วขอบคุณฟรีคล้ายกัน(ถ้าคุณสามารถเห็นความคิดเห็นที่ถูกลบคุณจะรู้ว่าสิ่งที่ ผมหมายถึง) นอกจากนี้ฉันคิดว่าฉันเข้าใกล้พอที่จะเข้าใจว่าทำไมวลีนี้ด้วยวิธีที่อาจมีประโยชน์มากกว่า ดังนั้นนี่คือความหวัง ...

ฉันมักชอบที่จะให้ทั้งหมดของฉันsed -eXpressions ไปหนึ่งถ้าฉันอาจ แต่ฉันยังมีการตั้งค่ามากขึ้นสำหรับการเป็นไปตามสเปคที่ใกล้เท่าที่จะทำได้โดยเฉพาะอย่างยิ่งเมื่อความแตกต่างจะมีจำนวนไม่เกินและ<space> -eแต่ฉันไม่สามารถทำได้ถ้าฉันไม่เข้าใจว่าทำไมฉันควรทำ นี่เป็นบทสรุปสั้น ๆ เกี่ยวกับสถานะปัจจุบันของความเข้าใจของฉัน:

  • ' -e 'แบ่ง portably สามารถยืนอยู่ในสำหรับsedสคริปต์\nแบ่ง ewline ในsedคำสั่งบรรทัดคำสั่ง ... ฉันยอมรับคลุมเครือเกี่ยวกับสาเหตุ

  • วงเล็บปีกกาปิดในsed {ฟังก์ชั่น}จะต้องนำหน้าด้วยตัว\nแบ่ง ewline ตามที่ระบุไว้ที่นี่:

    • <right-brace>จะนำหน้าด้วย<newline>และสามารถนำหน้าหรือตาม<blank>ตัวอักษร
  • \nแบ่ง ewline เป็นสิ่งจำเป็นในทำนองเดียวกันต่อไปนี้การใช้งานใด ๆ ... a, b, c, i, r, t, หรือw:

แต่ฉันไม่เข้าใจชัดเจนว่านิยามของ{ฟังก์ชัน}เกี่ยวข้องกับตัว!ดำเนินการที่ไม่ได้อย่างไร การกล่าวถึงเพียงฉันพบของผู้ประกอบการปฏิเสธในรัฐข้อมูลจำเพาะ:

  • ฟังก์ชั่นสามารถนำหน้าด้วย!ตัวละครหนึ่งตัวหรือมากกว่าในกรณีนี้ฟังก์ชั่นจะถูกนำไปใช้ถ้าที่อยู่ไม่ได้เลือกพื้นที่รูปแบบ

นี่หมายถึงการใช้ที่!แสดงถึง{การจัดฟัน}? สิ่งที่$!คำสั่ง - พวกเขาควรจะแยกออกจากกันโดย' -e 'แบ่ง? นี่คือสิ่งที่ได้รับการแก้ไขเมื่อStéphaneเพิ่งแก้ไขคำตอบของฉันล่าสุด

ฉันคิดว่ามันเป็นทั้ง!โอเปอเรเตอร์การปฏิเสธหรือเป็นbคำสั่งฟาร์มปศุสัตว์ที่เขาระบุในการแก้ไขของเขา - หรืออาจเป็นทั้งสองอย่างในคราวเดียว - แต่ฉันไม่รู้และควรจะชอบ ถ้ามันเป็นเพียงbงบไร่แล้วผมเชื่อว่าdจะทำในสถานที่และขจัดความจำเป็นในการที่' -e 'หยุดพัก แต่ฉันอยากจะให้แน่ใจก่อนที่จะ hazarding สามPOSIXifiedคำตอบ คุณช่วยได้ไหม

ฉันมีความเสี่ยงหลังจากทั้งหมดแต่ไม่ได้มีความมั่นใจที่ดีใด ๆ ...


ด้วยb;n;:bคุณจะแยกไปยังป้ายกำกับที่เรียกว่า";n;:b"ในประวัติและ POSIX seds (และ GNU sed ไม่ได้อยู่ในเรื่องนั้น)
Stéphane Chazelas

@ StéphaneChazelas - ฉันได้:ส่วน - คุณขับรถกลับบ้านเมื่อหลายเดือนก่อน แต่ผมไม่เข้าใจว่าทำไมที่สองsedคำสั่งเป็นทำนองเดียวกันPOSIXified
mikeserv

1
ไม่ว่าในกรณีใด POSIX spec สำหรับฉันsedก็ไม่ชัดเจน ฉันเคยขอคำชี้แจงมาก่อนสองสามครั้งแล้ว แต่ฉันไม่คิดว่ามันจะได้รับการอัพเดท การทดสอบที่ดีคือการลองใช้ชุดเครื่องมือมรดกตกทอด (Solaris one ซึ่งได้มาจากต้นฉบับและ POSIX spec นั้นยึดตาม)
Stéphane Chazelas

1
@syntaxerror - ฉันไม่เชื่อว่าเป็นกรณีนี้เลย ถ้าคุณอ่านข้อมูลจำเพาะคุณจะพบว่าs///ubstitutions จะ spec'd ที่จะยอมรับการผูกมัดกับ; . มันได้รับพร่ามัวรอบคำสั่งที่ต้องคั่นด้วย newline และวิธี-eสามารถยืนในกรณีที่ - อย่างน้อยมันก็ทำเพื่อฉัน ive ยังสะดุดในsedที่ไม่ตีความพวกเขาสวยสลับกันได้ว่า
mikeserv

1
@syntaxerror - ฉันชอบ แต่คุณควรรู้ว่าคุณไม่จำเป็นต้องใช้;ก่อนขึ้นบรรทัดใหม่ - ขึ้นบรรทัดใหม่ได้ดี สุจริตคุณสามารถทำได้โดยไม่ต้อง-eและทุกอย่างสิ้นเชิงและเพียงแค่เขียนไฟล์เช่น#!/bin/sedกับแต่ละคำสั่งบนบรรทัดใหม่ - ;หรือผู้ที่ไม่จำเป็นต้องมีตัวคั่นเช่นคั่นแทนด้วย คนที่ไม่จำเป็นต้องมีการขึ้นบรรทัดใหม่มักจะมีคนที่ใช้การป้อนข้อมูลโดยพลการ - :ชื่อฉลากและคำสั่งที่อ้างถึงพวกเขาเช่นbหรือtหรือปิด}curlies สำหรับฟังก์ชั่นหรือrอี๊ดและwพระราชพิธีซึ่งใช้ชื่อไฟล์ args พวกเขาทุกคนต้อง portably \nจะตามมาด้วย
mikeserv

คำตอบ:


4

ดังนั้นจึงเป็นคำถามที่สูงเวลานี้มีคำตอบและแม้ว่าในที่สุดฉันก็ใช้วิธีการทำอย่างถูกต้องในทุกกรณีที่ผ่านมาเมื่อไม่นานมานี้ฉันเพิ่งจัดการได้อย่างเป็นรูปธรรมที่เข้าใจเนื้อหาในมาตรฐาน . มันระบุไว้จริง ๆ แล้วมันค่อนข้างเรียบง่าย - ฉันแค่มองข้ามอย่างโง่เขลาหลายครั้งฉันเดา

ส่วนที่เกี่ยวข้องของข้อความทั้งหมดอยู่ภายใต้หัวข้อ ...

  • การแก้ไขคำสั่งในsed :

    • ข้อความโต้แย้งจะต้องประกอบด้วยหนึ่งหรือมากกว่าหนึ่งบรรทัด แต่ละ\newline ที่ฝังในข้อความจะต้องนำหน้าด้วย\แบ็กสแลช เครื่องหมายแบ็กสแลชอื่น ๆ ในข้อความจะถูกลบออกและอักขระต่อไปนี้จะต้องได้รับการปฏิบัติ

    • rและwคำสั่งคำกริยาและwธงกับsคำสั่งที่ใช้เป็นตัวเลือก rfile (หรือwfile ) พารามิเตอร์แยกออกจากคำสั่งคำกริยาตัวอักษรหรือธงโดยหนึ่งหรือมากกว่า<blank>s; การใช้งานอาจอนุญาตให้มีการแยกศูนย์เป็นส่วนขยาย

    • คำสั่งกริยาอื่น ๆ กว่า{, a, b, c, i, r, t, w, :และ#สามารถตามด้วย;อัฒภาค, ตัวเลือก<blank>sและคำกริยาคำสั่งอื่น อย่างไรก็ตามเมื่อใช้sกริยาคำสั่งกับwแฟล็กการตามด้วยคำสั่งอื่นในลักษณะนี้จะสร้างผลลัพธ์ที่ไม่ได้กำหนดไว้

...ใน...

  • ตัวเลือก: หลายรายการ-eและ-fตัวเลือกอาจมีการระบุ คำสั่งทั้งหมดจะถูกเพิ่มไปยังสคริปต์ตามลำดับที่ระบุโดยไม่คำนึงถึงที่มา

    • -e สคริปต์ - เพิ่มคำสั่งแก้ไขที่ระบุโดยสคริปต์ option-อาร์กิวเมนต์ที่ส่วนท้ายของสคริปต์คำสั่งแก้ไข สคริปต์ตัวเลือกอาร์กิวเมนต์จะต้องมีคุณสมบัติเช่นเดียวกับสคริปต์ถูกดำเนินการตามที่อธิบายไว้ในตัวถูกดำเนินการส่วน

    • -f script_file - เพิ่มคำสั่งแก้ไขในไฟล์script_fileที่ส่วนท้ายของสคริปต์

และสุดท้ายใน ...

  • ถูกดำเนินการ:

    • สคริปต์ - สตริงที่จะใช้เป็นสคริปต์ของคำสั่งแก้ไข แอปพลิเคชันจะต้องไม่นำเสนอสคริปต์ที่ละเมิดข้อ จำกัด ของไฟล์ข้อความยกเว้นว่าตัวอักษรสุดท้ายไม่จำเป็นต้องเป็น\newline

ดังนั้นเมื่อคุณนำมาใช้พร้อมกันมันทำให้รู้สึกว่าคำสั่งใด ๆ ซึ่งเป็นทางเลือกตามด้วยพารามิเตอร์โดยไม่มีตัวคั่นที่กำหนดไว้ล่วงหน้า(ตรงข้ามกับs d sub d repl d flagตัวอย่าง)ควรกำหนดขอบเขตที่\newline ที่ไม่ใช้ค่า Escape

มันก็พิสูจน์ว่า; เป็นตัวคั่นที่กำหนดไว้ล่วงหน้า แต่ในกรณีที่ใช้;สำหรับการใด ๆ ของ[aic]คำสั่งที่จะเลี่ยงที่ parser แยกต่างหากจะรวมอยู่ในการดำเนินการเฉพาะสำหรับบรรดาสามคำสั่ง - แยกต่างหากนั่นคือจากแยกวิเคราะห์ที่ใช้สำหรับการ[:brw]ยกตัวอย่างเช่น หรืออื่น ๆ ที่ดำเนินการจะต้องมีการกำหนดว่า; ยังจะทับขวาหนีภายในข้อความพารามิเตอร์และมันเติบโตขึ้นมีความซับซ้อนมากขึ้นจากที่นั่น

หากฉันกำลังเขียนสิ่งsedที่ฉันต้องการให้เป็นไปตามมาตรฐานและมีประสิทธิภาพฉันจะไม่เขียนโปรแกรมแยกวิเคราะห์เช่นนั้นฉันคาดว่า - ยกเว้นว่าอาจ[aic]จะเป็นข้อผิดพลาดทางไวยากรณ์หากไม่ได้ตามด้วย\newline ทันที แต่นั่นเป็นปัญหาโทเค็นอย่างง่าย - กรณีตัวคั่นสุดท้ายโดยทั่วไปจะเป็นปัญหามากกว่า ฉันแค่เขียนมันเพื่อ:

sed -e w\ file\\ -e one -e '...;and more commands'

...และ...

sed -e a\\ -e appended\\ -e text -e '...;and more commands'

... จะทำงานคล้ายกันมากโดยในครั้งแรกที่จะสร้างและเขียนไฟล์ชื่อ:

file
one

... และอันที่สองจะต่อท้ายข้อความในบรรทัดปัจจุบันบนเอาต์พุตเช่น ...

appended
text

... เพราะทั้งคู่จะแบ่งรหัสการแยกวิเคราะห์เดียวกันสำหรับพารามิเตอร์

และเกี่ยวกับปัญหา{ ... }และ$!- ดีฉันออกจากที่นั่น คำสั่งเดียวนำหน้าด้วยที่อยู่ไม่ใช่ฟังก์ชั่น แต่มันเป็นเพียงคำสั่งที่จ่าหน้า เกือบทุกคำสั่ง - รวมทั้ง{ นิยามฟังก์ชัน }มีการระบุที่จะยอมรับ/one/หรือ/one/,/two/ที่อยู่ - มีข้อยกเว้นของ#ความคิดเห็นและความหมายฉลาก: และที่อยู่สามารถเป็นได้ทั้งหมายเลขบรรทัดหรือรายการด่วนปกติและสามารถปฏิเสธ!ได้ ดังนั้นทั้งหมด ...

$!d
/address/s/ub/stitution/
5!y/d/c/

... สามารถตามด้วย;คำสั่งและอื่น ๆ ตามมาตรฐาน แต่ถ้าต้องการคำสั่งเพิ่มเติมสำหรับที่อยู่เดียวและที่อยู่นั้นไม่ควรถูกประเมินใหม่หลังจากการดำเนินการของแต่ละคำสั่งดังนั้น{ฟังก์ชั่น}ควรจะใช้เช่น:

/address/{ s//replace addressed pattern/
           s/do other conditional/substitutions/
           s/in the same context/without/
           s/reevaluating/address/
}

... ที่{ไม่สามารถติดตามบนบรรทัดเดียวกันโดยการปิด}และการปิด}ไม่สามารถเกิดขึ้นได้ยกเว้นที่จุดเริ่มต้นของบรรทัด แต่ถ้าคำสั่งที่มีอยู่ไม่ควรตามมาด้วย\newline ก็ไม่จำเป็นต้องอยู่ในฟังก์ชันเช่นกัน ดังนั้นs///ubstitutions ข้างต้นทั้งหมด - และแม้แต่}วงเล็บปีกกาปิดสามารถติดตามได้ด้วย;เครื่องหมายอัฒภาคและคำสั่งเพิ่มเติมได้

ฉันพูดถึง\nตัวคั่น ewline ต่อไป แต่คำถามกลับเป็นเรื่องเกี่ยวกับ-eคำสั่ง xpression แทนฉันรู้ แต่ทั้งสองเป็นหนึ่งเดียวและเหมือนกันและความสัมพันธ์ที่สำคัญคือสคริปต์สามารถเป็นอาร์กิวเมนต์บรรทัดคำสั่งตามตัวอักษรหรือไฟล์ที่มีอย่างใดอย่างหนึ่ง-[ef]และที่ทั้งสองจะถูกตีความว่าเป็นไฟล์ข้อความ(ซึ่งถูกระบุให้สิ้นสุดใน\newline)แต่ไม่จำเป็นต้องสิ้นสุดใน\newline จริงๆ โดยนี้ผมสามารถ reasonbly (ฉันหวังว่า)สรุปว่า\0NULข้อโต้แย้งที่คั่นหมายถึงสิ้นสุด\newline และเป็นทุกข้อโต้แย้งอุทธรณ์ได้รับอย่างน้อย)\0NULคั่นอยู่แล้วแล้วก็ควรจะทำงานได้ดี

ในความเป็นจริงในทางปฏิบัติในทุกกรณี แต่สิ่งที่มาตรฐานระบุ\backslash หนีขึ้นบรรทัดใหม่ควรจะต้องฉันพบ portably ...

sed -e ... -e '...\' -e '...'

... เพื่อการทำงานเช่นกัน และในทุกกรณี - อีกครั้งในทางปฏิบัติ - ในกรณีที่\nจำเป็นต้องใช้ ewline ที่ไม่ใช้การหลบหนี...

sed -e '...' -e '...'

... ก็ได้ผลสำหรับฉันเช่นกัน ข้อยกเว้นเดียวที่ฉันกล่าวถึงข้างต้นคือ ...

sed -e 's/.../...\' -e '.../'

... ซึ่งใช้ไม่ได้กับการนำไปใช้ในการทดสอบใด ๆ ของฉัน ฉันค่อนข้างแน่ใจว่าตรงตามความต้องการของไฟล์ข้อความและความจริงที่s/// มาพร้อมกับตัวคั่นดังนั้นจึงไม่มีเหตุผลที่คำสั่งเดียวควรขยาย\0NULอาร์กิวเมนต์ที่มีตัวคั่น

ดังนั้นโดยสรุปนี่เป็นบทสรุปสั้น ๆ ของวิธีพกพาในการเขียนหลายชนิด sedคำสั่ง :

สำหรับใด ๆ ของ[aic]:

...commands;[aic]\
text embedded newline\
delimiting newline
...more;commands...

...หรือ...

sed -e '...commands;[aic]\' -e 'text embedded newline\' -e 'delimiting newline' -e '.;.;.'

สำหรับใด ๆ ของ[:rwtb]ที่พารามิเตอร์เป็นตัวเลือก (สำหรับทุกคน แต่:)แต่ delimiting \newline เป็นไม่ได้ โปรดทราบว่าฉันไม่เคยมีเหตุผลที่จะลองพารามิเตอร์ป้ายกำกับหลายบรรทัดตามที่จะใช้กับ[:tb]แต่การwriting / reading ไปยังหลายบรรทัดในพารามิเตอร์ไฟล์ [rw]มักจะได้รับการยอมรับโดยไม่มีคำถามโดยseds ฉันได้ทดสอบตราบใดที่\newline ในตัวถูกหลบหนีด้วย\แบ็กสแลช ถึงกระนั้นมาตรฐานไม่ได้ระบุฉลากและ[ไฟล์ rw]โดยตรงพารามิเตอร์ควรจะแยกวิเคราะห์เหมือนกันกับข้อความพารามิเตอร์และไม่ได้กล่าวถึง\newlines เกี่ยวกับสองข้อแรกยกเว้นเมื่อกำหนดขอบเขตไว้

...commands;[:trwb] parameter
...more;commands...

...หรือ...

sed -e '[:trwb] parameter' -e '...'

... ที่ดังกล่าวข้างต้นเป็นทางเลือกสำหรับ<space>[:tb]

และสุดท้าย ...

...;address[!]{ ...function;commands...
};...more;commands....

...หรือ...

sed -e '...;address[!]{ ...function;commands...' -e '};...more;commands...'

... ที่ใด ๆ ของคำสั่งดังกล่าว(ยกเว้น:)ยอมรับอย่างน้อยหนึ่งที่อยู่และซึ่งอาจเป็น/regexp /หรือหมายเลขบรรทัดและอาจถูกปฏิเสธด้วย!แต่ถ้ามากกว่าหนึ่งคำสั่งมีความจำเป็นสำหรับการประเมินที่อยู่เดียวแล้วต้องใช้วงเล็บปีกกา{บริบทของฟังก์ชัน }ฟังก์ชั่นสามารถมีได้หลายคู่\nคำสั่งที่คั่นด้วย ewline ได้คำ แต่แต่ละคำสั่งต้องคั่นด้วยวงเล็บปีกกาตามที่ควรเป็น

และนั่นคือวิธีเขียนsedสคริปต์แบบพกพา


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