ใครสามารถอธิบายวิธีการsedทำงานของคำสั่งนี้
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedวิธีนี้! :)
ใครสามารถอธิบายวิธีการsedทำงานของคำสั่งนี้
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedวิธีนี้! :)
คำตอบ:
ใน sed s/pattern/replacement/optionsคำสั่งแทนมักจะเขียนเป็น แต่ก็ไม่จำเป็นต้องใช้/- คุณสามารถใช้ตัวละครอื่น ๆ ถ้ามันเป็นความสะดวกสบายดังนั้นมันอาจจะเป็นหรือs@pattern@replacement@options เป็นเหมือน- แทนที่ทั้งหมดด้วยช่องว่าง ในทำนองเดียวกันแทนที่ทั้งหมดด้วย(แบ็กสแลชเดี่ยวคืออักขระ escape ใน sed ดังนั้นคุณต้องมีสองสแลชเพื่อรับแบ็กสแลชจริง)s:foo:bar:gs@+@ @gs/+/ /g+s@%@\\x@g%\x
สตริงเช่นนั้นจะกลายเป็นfoo+%2Fbar จะขยายลำดับหนีแบคสแลชเช่น(อักขระ ASCII ที่มีค่าเลขฐานสิบหกเป็น 2F ซึ่งก็คือ) เพื่อให้คุณได้ในที่สุดfoo \x2Fbarprintf "%b"\x2F/foo /bar
คำสั่งที่คุณถามเกี่ยวกับการถอดรหัส+es และ%ลำดับจาก URLไม่ใช่sedคำสั่งมันเป็นไพพ์ไลน์ที่ประมวลผลอินพุตsedจากนั้นไพพ์ไปยังxargsเพื่อการประมวลผลเพิ่มเติม ก่อนอื่นให้ดูที่sedคำสั่ง:
sed 's@+@ @g;s@%@\\x@g'
คุณอาจคุ้นเคยกับการเห็น/มากกว่า@ตัวคั่นซึ่งทำได้ง่าย ๆ โดยไม่มีความยุ่งยากเนื่องจาก/ปรากฏในรูปแบบการค้นหาหรือข้อความทดแทนใด ๆ คำสั่งนี้เทียบเท่า:
sed 's/+/ /g;s/%/\\x/g'
ชอบ/, เป็นตัวละครที่เครื่องหมายวรรคตอนที่ดีที่ดีเลิศสำหรับ@sed
ในแต่ละบรรทัดอินพุต:
s@+@ @g( s/+/ /g) ทดแทน ( s) การเกิดขึ้นของ+ด้วยช่องว่าง สิ่งนี้มีผลต่อ+es ทั้งหมดในบรรทัด ( g) ไม่ใช่แค่อันแรก
; สิ้นสุดการกระทำ ("คำสั่ง") และช่วยให้คุณสามารถระบุการกระทำอื่นใน "สคริปต์เดียวกัน"
s@%@\\x@g( s/%/\\x/g) ทดแทน ( s) การเกิดขึ้นของด้วย% \xเหมือนก่อนหน้านี้มันทำงานได้ทั้งหมดมากกว่าแค่แค่บรรทัดแรกของแต่ละบรรทัด ( g)
ในเป็นตัวแทนเพียงหนึ่งเพราะมีความหมายพิเศษเพื่อ ความหมายพิเศษของมันนั้นจริง ๆ แล้วเป็นตัวละครที่คุณใช้เพื่อกำจัดความหมายพิเศษของตัวละครอื่นที่ตามมาซึ่งจะมีความหมายพิเศษเป็นอย่างอื่น ดังนั้นจึงต้องหนีออกมาเป็น\\x\\\\sed\\
ตอนนี้ให้ดูที่คำสั่งที่มีวัตถุประสงค์คือการทำงานxargsprintf
xargsสร้างบรรทัดคำสั่ง หากคุณเรียกใช้โดยที่หนึ่งคำหรือมากกว่านั้นจะทำงานโดยมีอาร์กิวเมนต์บรรทัดคำสั่งเพิ่มเติมอ่านจากอินพุต ในกรณีนี้อินพุตเป็นเอาต์พุตของเนื่องจาก pipe ( ) โดยปกติจะตีความช่องว่างใด ๆ ในอินพุตเพื่อแปลว่าข้อความก่อนและหลังถือว่าเป็นอาร์กิวเมนต์แยกต่างหาก แต่ตัวเลือกทำให้แยกอาร์กิวเมนต์ที่เกิดขึ้นของอักขระ nullแทนxargs command...command...xargscommand...xargssed|xargs-0
ในการใช้คำสั่งของคุณอย่างตั้งใจอักขระ null จะไม่ปรากฏขึ้นและxargsจะทำงานprintf %bโดยมีอาร์กิวเมนต์บรรทัดคำสั่งเพิ่มเติมเพียงหนึ่งเอาต์พุตของsedคำสั่ง ดังนั้นในขณะที่ไม่เทียบเท่ากันโดยทั่วไปในกรณีนี้ไพพ์ไลน์ทั้งหมดอาจถูกเขียนแทนเช่นนี้โดยใช้การทดแทนคำสั่งแทนxargs:
printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
สำหรับสิ่งที่printfตั้งใจจะทำที่นี่เช่นเดียวกับที่ muru บอกว่าตัว%bระบุรูปแบบจะใช้และพิมพ์อาร์กิวเมนต์ (เช่น%s) แต่ทำให้แบ็กสแลชหนี - จากการเรียงลำดับsedคำสั่งทางด้านซ้ายของไพพ์ถูกเขียนขึ้นเพื่อสร้าง - เพื่อแปล เป็นตัวอักษรพวกเขาเป็นตัวแทน
สมมติว่าฉันใช้คำสั่งนั้นและส่งผ่านhttp://foldoc.org/debugging%20by%20printfเป็นอินพุต ฉันได้รับhttp://foldoc.org/debugging by printfเป็นผลลัพธ์เนื่องจาก%20ลำดับถูกแปลเป็นช่องว่าง
นั่นคือความงามของsedมันใช้กระบวนทัศน์ของตัวเอง ... หลังจากคำสั่ง (เช่นsหรือtrหรือไม่มีอะไร) ตัวละครต่อไปถือว่าเป็นตัวแยก
คุณควรเลือกอย่างชาญฉลาดเพื่อหลีกเลี่ยงการรบกวนกับเชลล์และคำสั่งเองและรักษาสิ่งที่สามารถอ่านได้ แต่มันก็ใช้ได้อย่างสมบูรณ์แบบที่จะเขียนสิ่งที่น่ากลัวอย่างเช่น:
echo 'arrival' | sed srarbrg
... และรับbrrivblผลซึ่งเป็นสิ่งที่คุณคาดหวัง คุณสามารถสนุกไปกับการทำให้เป็นความลับได้เช่นใน:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
การใช้งานทั่วไปคือการใช้เครื่องหมายสแลชเป็นตัวคั่น แต่เมื่อนิพจน์ของคุณมีตัวคั่นมันจะทำให้ง่ายต่อการรับรู้ว่าเจตนาคืออะไร ตัวคั่นของคุณสามารถเป็นอะไรก็ได้ในช่วง ASCII8 (ตัวคั่นหลายไบต์เช่น£กระตุ้นข้อผิดพลาด)
เพียงจำไว้ว่าเป้าหมายคือการทำให้สิ่งต่าง ๆ ง่ายขึ้นไม่เป็นความลับ
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sedคำสั่งเป็นของเล่นพัฒนาสมองด้วยเช่นกัน