เข้าร่วม:“ ไฟล์ 2 ไม่เรียงตามลำดับ”


13

ฉันมีสองไฟล์ _jeter3.txt และ _jeter1.txt

ฉันได้ตรวจสอบพวกเขาทั้งสองเรียงในคอลัมน์ที่ 20 ใช้ sort -c

sort -t '     ' -c -k20,20 _jeter3.txt
sort -t '     ' -c -k20,20 _jeter1.txt
#no errors

แต่มีข้อผิดพลาดเมื่อฉันต้องการjoinไฟล์ทั้งสองมันบอกว่าไฟล์ที่สองไม่ได้เรียง:

join -t '   ' -1 20 -2 20 _jeter1.txt _jeter3.txt > /dev/null
join: File 2 is not in sorted order

ฉันไม่เข้าใจว่าทำไม

cat /etc/*-release #FYI
openSUSE 11.0 (i586)
VERSION = 11.0

อัปเดต : การใช้ ' sort -f' และjoin -i(ทั้งตัวพิมพ์เล็กและใหญ่) จะแก้ไขปัญหาได้ แต่มันไม่ได้อธิบายปัญหาเบื้องต้นของฉัน

อัปเดต : รุ่นของการเรียง & เข้าร่วม:

> join --version
join (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)

> sort --version
sort (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)

คุณช่วยให้เราได้ผลลัพธ์ของ "เข้าร่วม - รุ่น" และ "เรียงลำดับ - รุ่น" เพียงเพื่อความสมบูรณ์? ฉันไม่สามารถเข้าร่วม gnu รุ่นเก่าบางรุ่นเพื่อให้ข้อความแสดงข้อผิดพลาดนั้นไม่ว่าในกรณีใด ๆ
Bruce Ediger

3
localeกรุณาโพสต์ข้อมูลตัวอย่างบางส่วนที่แสดงปัญหาและการส่งออกของ
Gilles 'ดังนั้นหยุดความชั่วร้าย'

คำตอบ:


25

ฉันได้รับข้อผิดพลาดเดียวกันกับ Ubuntu 11.04 ด้วยsortและjoinทั้งสองรุ่น (GNU coreutils) 8.5

ไม่เข้ากันอย่างชัดเจน ที่จริงแล้วsortคำสั่งนั้นดูเหมือนว่าจะเป็นบั๊ก: ไม่มีความแตกต่างที่มีหรือไม่มีตัวเลือก-f( --ignore-case) เมื่อเรียงลำดับอยู่เสมอก่อนaaB aBaอักขระที่ไม่ใช่ตัวอักษรและตัวเลขดูเหมือนว่าจะถูกละเว้นเสมอ ( abcอยู่ก่อนหน้าab-x)

เข้าร่วมดูเหมือนจะคาดหวังสิ่งที่ตรงกันข้าม ... แต่ฉันมีทางออก

อันที่จริงแล้วสิ่งนี้เชื่อมโยงกับลำดับการเรียง: ใช้LANG=en_EN sort -k 1,1 <myfile> ...แล้วLANG=en_EN join ...กำจัดข้อความ

ความเป็นสากลเป็นรากฐานของความชั่วร้าย ... (ไม่มีใครบันทึกไว้อย่างชัดเจน)


ดังนั้นหากใช้ทั้งคู่LANG=en_ENแล้วมันจะใช้งานได้แน่นอนหรือไม่ มันจะใช้งานได้สำหรับภาษาใด ๆ ตราบใดที่ทั้งสองใช้สถานที่เดียวกัน เราสามารถพูดได้ว่าความแตกต่างระหว่างsortและjoinคือพวกเขาใช้สถานที่ที่แตกต่างกันโดยค่าเริ่มต้น?
Aaron McDaid

เป็น-kตัวเลือกคำตอบที่นี่หรือคือมันLANG=en_EN? มันไม่ชัดเจนว่าโซลูชันที่แน่นอนคืออะไรที่นี่
ผู้ใช้

5

คุณเรียงลำดับด้วยตัวเลขหรือไม่ ฉันพบว่าการเติมคอลัมน์เป็นศูนย์ที่ฉันเข้าร่วมไม่ได้แก้ไขปัญหานี้ให้ฉัน

cat file.txt \
     | awk -F"   " '{ $20=sprintf("%06s", $20); print $0}' \
     | sort > readytojoin.txt

5

หากคุณแน่ใจว่าคุณจัดเรียงไฟล์อินพุตของคุณอย่างถูกต้องและสามารถจับคู่ไฟล์เหล่านั้นได้คุณสามารถหลีกเลี่ยงข้อผิดพลาดด้านบนได้โดยการรัน join --nocheck-order file1.txt file2.txt


4

sort โดยค่าเริ่มต้นใช้ทั้งบรรทัดเป็นคีย์

join ใช้เฉพาะฟิลด์ที่ระบุเป็นคีย์

คุณต้องแก้ไขความไม่ลงรอยกันนี้ด้วยการ จำกัด การเรียงลำดับเพื่อใช้คีย์ที่คุณต้องการเข้าร่วมเท่านั้น

สถานะหน้าเข้าร่วมของมนุษย์:

สำคัญ: ต้องเรียงลำดับ FILE1 และ FILE2 บนฟิลด์เข้าร่วม เช่นใช้ 'sort -k 1b, 1' ถ้า> 'เข้าร่วม' ไม่มีตัวเลือก หมายเหตุการเปรียบเทียบปฏิบัติตามกฎที่ระบุโดย 'LC_COLLATE' หากไม่ได้เรียงลำดับอินพุต> และบางบรรทัดไม่สามารถเข้าร่วมได้จะมีข้อความเตือนปรากฏขึ้น


2
LOCALE=C sort ...
LOCALE=C join ...

นี่จะช่วยแก้ปัญหาของคุณ ปัญหาดังที่ระบุโดย @Michael คือลำดับการเรียงซึ่งขึ้นอยู่กับการตั้งค่า LOCALE ของคุณ


2

โปรดทราบว่าหากคุณเห็นข้อผิดพลาดนี้และคุณได้เรียงลำดับแล้วในคอลัมน์ที่เฉพาะเจาะจงและกำลังตีหัวของคุณกับผนังเช่น sort -k4,4 คุณอาจต้องตั้งค่าตัวคั่นสำหรับคำสั่ง sort

เห็นได้ชัดว่า OP ได้ทำสิ่งนี้ด้วย -t '' แต่สำหรับข้อความที่คั่นด้วยแท็บปกติฉันขอแนะนำ

sort -t $'\t' ...

คำสั่ง sort สามารถรวมช่องว่างเป็นตัวคั่นตามค่าเริ่มต้นแม้ในบางสิ่งที่ดูเหมือนไฟล์ที่คั่นด้วยแท็บ (โดยเฉพาะถ้ามีช่องว่างภายในคอลัมน์ที่คุณเรียงลำดับ)

ถ้าคุณผ่านการเรียงลำดับข้อมูลที่จะเข้าร่วมและคุณมี

join -t $'\t' ...

จากนั้นสิ่งนี้กลายเป็นสาเหตุทำให้เกิดข้อผิดพลาดเกี่ยวกับการยกเลิกการเรียงลำดับ ตามที่ระบุไว้ข้างต้นการเข้าร่วมอาจไม่ยอมรับ -t ''


1

สำหรับการเข้าร่วมการโต้แย้งหลังจาก -t เป็นตัวละคร สำหรับการเรียงคุณสามารถจัดหาตัวแยกการเรียงที่ยาวกว่า ฉันคิดว่าคุณอาจเข้าร่วมไฟล์ในฟิลด์อื่นที่คุณต้องการและการเพิกเฉยกรณีและปัญหาแก้ไขโดยบังเอิญ

และฉันเห็นด้วยกับ Gilles ข้อมูลตัวอย่างนั้นจะเป็นประโยชน์

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