ใครสามารถอธิบายวิธีการ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:g
s@+@ @g
s/+/ /g
+
s@%@\\x@g
%
\x
สตริงเช่นนั้นจะกลายเป็นfoo+%2Fbar
จะขยายลำดับหนีแบคสแลชเช่น(อักขระ ASCII ที่มีค่าเลขฐานสิบหกเป็น 2F ซึ่งก็คือ) เพื่อให้คุณได้ในที่สุดfoo \x2Fbar
printf "%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
\\
ตอนนี้ให้ดูที่คำสั่งที่มีวัตถุประสงค์คือการทำงานxargs
printf
xargs
สร้างบรรทัดคำสั่ง หากคุณเรียกใช้โดยที่หนึ่งคำหรือมากกว่านั้นจะทำงานโดยมีอาร์กิวเมนต์บรรทัดคำสั่งเพิ่มเติมอ่านจากอินพุต ในกรณีนี้อินพุตเป็นเอาต์พุตของเนื่องจาก pipe ( ) โดยปกติจะตีความช่องว่างใด ๆ ในอินพุตเพื่อแปลว่าข้อความก่อนและหลังถือว่าเป็นอาร์กิวเมนต์แยกต่างหาก แต่ตัวเลือกทำให้แยกอาร์กิวเมนต์ที่เกิดขึ้นของอักขระ nullแทนxargs command...
command...
xargs
command...
xargs
sed
|
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
คำสั่งเป็นของเล่นพัฒนาสมองด้วยเช่นกัน