ลบบรรทัดที่ซ้ำกันที่อยู่ติดกันในขณะที่รักษาการสั่งซื้อ


11

ฉันมีไฟล์ที่มีหนึ่งคอลัมน์ที่มีชื่อที่ซ้ำหลายครั้งในแต่ละครั้ง ฉันต้องการรวมการทำซ้ำแต่ละครั้งเป็นหนึ่งในขณะที่การทำซ้ำชื่ออื่นที่มีชื่อเดียวกันที่ไม่ติดกับชื่อซ้ำกันอื่น ๆ

เช่นฉันต้องการเลี้ยวซ้ายไปทางขวา:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

นี่คือสิ่งที่ฉันใช้: perl -ne 'print if ++$k{$_}==1' file.txt > file2.txt อย่างไรก็ตามวิธีนี้จะช่วยให้ตัวแทนหนึ่งคนจากด้านซ้ายเท่านั้น (เช่น Golb1 และ Akna ไม่ซ้ำกัน)

มีวิธีในการเก็บชื่อที่ไม่ซ้ำกันสำหรับแต่ละบล็อกในขณะที่รักษาชื่อที่ทำซ้ำในบล็อกหลายบล็อกที่ไม่ติดกันหรือไม่

คำตอบ:


23

uniq จะทำสิ่งนี้เพื่อคุณ:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna

2
ว้าวนั่นเป็นเรื่องง่ายที่น่าอาย! ขอบคุณ!
อายุ 87

@ Age87 Unix ยอดเยี่ยมมาก! ใช้งานได้เพียงเพราะคุณคาดหวังว่ารายการที่ซ้ำกันจะอยู่ติดกันแล้ว (หรือไม่ต้องการลบรายการที่ไม่อยู่ติดกัน) โดยปกติคำแนะนำคือการใช้sort | uniq
jpaugh

1
หรือมากกว่าโดยsort -u
สังเขป


6

ลองนี้ - บันทึกบรรทัดก่อนหน้าและเปรียบเทียบกับบรรทัดปัจจุบัน

$ perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

คุณเคยติดแท็กuniqด้วย - คุณลองหรือยัง

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

1

ด้วยsedสามารถทำได้ดังนี้:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

ที่นี่เรามีในพื้นที่รูปแบบตลอดเวลา 2 บรรทัด เมื่อการเปรียบเทียบระหว่างสิ่งเหล่านี้ล้มเหลวเราจะพิมพ์ตัวแรกและตัดมันจากด้านหน้าแล้วย้อนกลับและต่อท้ายบรรทัดถัดไปในพื้นที่รูปแบบ ล้างซ้ำ ...

การใช้Perlในโหมด slurp เราจะถือว่าไฟล์ทั้งหมดเป็นสตริงยาวหนึ่งสตริงที่ใช้ regex ซึ่งทำการเปรียบเทียบให้คุณ

perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file

0

คำถามเกี่ยวกับวิธีการแก้ปัญหาของ Rakesh Sharma

ถ้าคุณมีไฟล์อินพุตเช่น:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

และคุณต้องการให้ไฟล์เอาต์พุตเป็น:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

บันทึกสิ่งที่หายไป:

-126.118 48.216

ฉันรู้ว่าคำสั่งที่ฉันต้องการนั้นคล้ายคลึงกับโซลูชันของคุณ:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

ไม่สามารถแก้ไขได้อย่างถูกต้องเพื่อพิมพ์ทั้งสองคอลัมน์และเรียงลำดับด้วยวิธีพิเศษนี้ด้วยค่าคอลัมน์ 2 เท่านั้น เคล็ดลับใด ๆ


sed -e '$!N' -e '/.*\.\([0-9]*\)\n.*\.\1$/!{P;D;}' -e 's/\n.*//;s/^/\n/;D' จะลบองค์ประกอบการทำซ้ำตามมา หมายเหตุ: GNU sedนี้ต้อง สำหรับPOSIXพฤติกรรมมันต้องการการเปลี่ยนแปลงเล็กน้อย
Rakesh Sharma
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.