ตัวเลือก '-s', '-t' และ '-c' ของคำสั่ง tr ทำงานใน Unix ได้อย่างไร


12

ฉันกำลังสับสนเกี่ยวกับวิธีการ-s, -tและ-cตัวเลือกการทำงานในTRคำสั่ง เมื่อฉันทำ

echo I am a good boy | tr good bad

ฉันได้รับผลลัพธ์:

I am a bddd bdy

นี้เป็นที่เข้าใจมากเนื่องจากซ้ำแล้วซ้ำอีกในo goodการเปลี่ยนแปลงครั้งสุดท้ายที่เป็นไปได้แทนoคือdและด้วยเหตุนี้ผลลัพธ์

ตอนนี้เมื่อฉันทำ

echo I am a good boy | tr -s good bad

ผลลัพธ์คือ

I am a bd bdy

-sตัวเลือกควรจะบีบทุกเกิดขึ้นซ้ำแล้วซ้ำอีกของตัวละครที่อยู่ในชุดละ 1 เป็นเกิดขึ้นเพียงครั้งเดียวแล้วเปลี่ยนตัวละครแต่ละตัวใน 1 ชุดลงไปในตัวละครที่สอดคล้องกันในชุดที่ 2 ซึ่งอยู่ในตำแหน่งเดียวกัน

ดังนั้นมันควรจะเป็น

I am a bad bay.

ทำไมการเปลี่ยนแปลง

ยิ่งกว่านั้นเมื่อฉันทำ

echo I am a good boy | tr -c good bad

ฉันเข้าใจ dddddddgoodddodd

อย่างไร-cการทำงานของตัวเลือกสำหรับการtrหมายถึงเช่นนี้หรือไม่?

และในที่สุด: วิธีการเปลี่ยนตัวเองจากเด็กดีไปเป็นเด็กเลว .... :): P นั่นคือ

echo I am a good boy | tr <something>ให้ผลลัพธ์เป็น: I am a bad boy.

คำตอบ:


12

-s สวิตช์: บีบ (ลบอักขระซ้ำ)

echo i am a good boy | tr -s good bad

เอาท์พุท: i am a bd bdy

มีสองสิ่งที่เกิดขึ้นเบื้องหลังที่ทำให้สิ่งนี้เกิดขึ้น ประการแรกถ้าอาร์กิวเมนต์ที่สองที่จะtrสั้นกว่าครั้งแรกแล้วตัวละครสุดท้ายใน ARG ที่ 2 จะถูกทำซ้ำเพื่อให้มันมีความยาวเท่ากับครั้งแรก ดังนั้นคำสั่งที่เทียบเท่าคือ:

echo i am a good boy | tr -s good badd

สิ่งอื่น ๆ ที่เกิดขึ้นคือเมื่อตัวละครในอาร์กิวเมนต์แรกซ้ำแล้วซ้ำอีกพวกเขาเขียนทับสิ่งที่เกิดขึ้นก่อนหน้านี้ (ฉันหมายถึงทั้งสองooในgood) สิ่งนี้ทำให้คำสั่งนี้เทียบเท่ากับ:

echo i am a good boy | tr -s god bdd

(ที่สองoเพื่อdแทนที่เขียนทับก่อนหน้านี้oเพื่อaแทนที่ทำให้มันซ้ำซ้อน)

หากไม่มี-sสวิตช์เอาต์พุตจะเป็นเช่นนั้น

i am a bddd bdy

ด้วย-sสวิตช์tr'บีบ' อักขระซ้ำ ๆ ใด ๆ ที่ระบุไว้ในอาร์กิวเมนต์สุดท้ายออกจากเอาต์พุตสุดท้าย:

i am a bd bdy

-c Switch: ส่วนประกอบ

-cสวิทช์ถูกนำมาใช้เพื่อให้ตรงกับส่วนประกอบของอาร์กิวเมนต์แรก (เช่นตัวละครทั้งหมดที่ไม่ได้ระบุไว้ในหาเรื่อง 1) ดังนั้น ARG 1 จะมีตัวอักษรจำนวนมาก (256-3) ตอนนี้สิ่งเดียวกันที่เกิดขึ้นกับ arg 2 เช่นเดียวกับในกรณีก่อนหน้า: ตัวละครสุดท้ายของ Arg 2 ได้รับการทำซ้ำเพื่อให้ตรงกับความยาวหรือ arg 1 ดังนั้นข้อความเดิม:

echo i am a good boy | tr -c good bad

เทียบเท่ากับ:

echo i am a good boy | tr abcefhijklmnp... baddddddddddd...

(หมายเหตุหายไปg, oและdในชุดแรกยังทราบว่าdจะเข้ามาแทนที่ตัวละครทุกตัวอื่น ๆ ในชุดที่สอง - รวมทั้งอักขระช่องว่าง)

นี่คือเหตุผลที่i am a good boyกลายเป็นdddddddgoodddodd

ข้อมูลเพิ่มเติมที่นี่: http://www.linuxjournal.com/article/2563


โดยทั่วไปถูกต้องยกเว้นว่า-sสวิตช์ทำให้trบีบอักขระใด ๆ จากอาร์กิวเมนต์สุดท้ายเป็นtr(ไม่ใช่ตัวแรกตามที่คุณพูด) ที่ทำซ้ำในอินพุต นี้ถูกบันทึกไว้ในบทความที่คุณเชื่อมโยงและมีการอธิบายในย่อหน้าสุดท้ายในส่วน "คำอธิบาย" ของหน้าคน
ravron

4

ความเข้าใจของคุณ-sไม่ถูกต้องมันจะแทนที่อักขระที่เกิดขึ้นซ้ำ ๆ ในชุดที่ 1 ในอินพุตด้วยอักขระเดียว มันไม่ได้ปรับเปลี่ยนการตั้งค่าเช่น

echo i am a good boy | tr -s god bad

จะช่วยให้

i am a bad bay

-cแทนที่ตั้งค่าตัวเลือก 1 กับส่วนประกอบของมัน (เช่น. ชุดของตัวละครทุกตัวไม่ได้มีอยู่ในชุด 1) คุณสามารถใช้วิธีนี้เพื่อลบทั้งหมดยกเว้นอักขระที่ระบุเช่น

echo i am a good boy | tr -cd gobdy

เอาท์พุท

goodboy

: ฉันมีจุดของคุณเกี่ยวกับตัวเลือก - s แต่คำถามของฉันคืออย่างไร: echo ฉันเป็นเด็กดี | TR -s ดีไม่ดีจะให้ผลลัพธ์เป็น: ฉัน bd bdy นี้เป็นไปได้เฉพาะเมื่อสิ่งนี้เกิดขึ้น: ครั้งแรกที่ฉันเป็นเด็กดีเปลี่ยนเป็นฉัน bddd bdy จากนั้นตัวเลือก -s เปลี่ยนการเกิดขึ้นของหลาย d เป็นโสด เช่น: ฉันเป็น bddd bdy แล้วเปลี่ยนเป็นฉัน bd bdy นี่คือสิ่งที่เกิดขึ้นจริงหรือ ได้โปรดทำลายสิ่งนี้ให้ฉันด้วยตัวเลือก -c echo ฉันเป็นเด็กดีอย่างไร tr -cd gobdy ให้สิ่งนี้: goodboy

1

คำตอบอื่น ๆ ปกคลุมtr's -s, -tและ-cตัวเลือก แต่เพื่อความสมบูรณ์:

คุณกำลังมีปัญหาเพราะคุณเลือกเครื่องมือที่ไม่ถูกต้อง

  • tr สำหรับการแปลงตัวละคร
  • sed ใช้สำหรับการแก้ไขสตรีม

เนื่องจากทั้งคู่goodและbadเป็นลำดับของตัวละครในสตรีมsedจะเป็นการจับคู่ที่ดีกว่า

echo I am a good boy | <something> ให้ผลลัพธ์เป็น: I am a bad boy

$ echo I am a good boy | sed s/good/bad/g
I am a bad boy

s/..../..../เป็นแทน สิ่งที่ตรงกับนิพจน์ทั่วไปแรกจะถูกแทนที่ด้วยนิพจน์ที่สอง การ/gตั้งค่าสถานะในตอนท้ายมีไว้สำหรับการแทนที่ส่วนกลางด้วยวิธีนี้การเกิดขึ้นทั้งหมดจะถูกแทนที่ไม่ใช่แค่ครั้งแรก

$ echo I am a good boy and a good boy is me. | sed s/good/bad/
I am a bad boy and a good boy is me.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/g
I am a bad boy and a bad boy is me.

0

ใช่. ตรง!

tr -s แทนที่อินสแตนซ์ของอักขระที่ซ้ำกันด้วยอักขระเดียว

(ผ่านหน้าคน)

ดังนั้นมันจะเป็นเช่นนี้:

จะแปลงไปgood bdddอินสแตนซ์ที่ซ้ำกันคือ 3 'd

ดังนั้นจึงแทนที่ทั้งสามอินสแตนซ์ด้วยอินสแตนซ์เดียว

นั่นคือมันทำให้มัน bd :)


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