Объединение файлов в Linux

Я использую Cygwin для объединения нескольких файлов. Тем не менее, я хотел знать, правильный ли мой подход или нет. Это и вопрос, и обсуждение :)

Сначала немного информации о файлах, которые у меня есть:

  1. Оба файла имеют символы ASCII, а также символы NON ASCII.
  2. Файл1 содержит 7899097 строк и имеет размер ~ 70,9 МБ.
  3. Файл2 содержит 14344391 строк и имеет размер ~ 136,6 Мб.

Информация о кодировке файла:

$ file -bi file1.txt
text/x-c++; charset=unknown-8bit

$ file -bi file2.txt
text/x-c++; charset=utf-8

$ file -bi output.txt
text/x-c++; charset=unknown-8bit

Это метод, которым я следую, чтобы объединить два файла, отсортировать их, а затем удалить все повторяющиеся записи:

  1. Я создаю временную папку и помещаю в нее оба текстовых файла.
  2. Я запускаю следующие команды, чтобы объединить оба файла, но сохраняю разрыв строки между двумя

    for file in *.txt; do
        cat $file >> output.txt
        echo >> output.txt
    done
    

Полученный файл output.txt содержит 22243490 строк и имеет размер 207,5 Мб.

Теперь, если я запускаю на нем команду сортировки, как показано ниже, я получаю сообщение об ошибке, поскольку внутри него присутствуют символы, отличные от ASCII (возможно, юникод, широкие символы):

sort -u output.txt
string comparison failed: Invalid or incomplete multibyte or wide character

Итак, я установил для переменной среды LC_ALL значение C, а затем выполнил команду следующим образом:

cat output.txt | sort -u | uniq >> result.txt

И в результате.txt содержит 22243488 строк и имеет размер 207,5 Мб.

Итак, result.txt совпадает с output.txt.

Теперь я уже знаю, что в output.txt много повторяющихся записей, тогда почему приведенные выше команды не могут удалить повторяющиеся записи?

Кроме того, учитывая большой размер файлов, я хотел знать, является ли это эффективным методом объединения нескольких файлов, их сортировки, а затем их уникальности?


person Neon Flash    schedule 22.07.2012    source источник
comment
Справедливо ли резюмировать ваш вопрос как - иметь возможность сортировать и объединять файлы данных с многобайтовыми символами? Установлена ​​ли для файлов кодировка UTF-8 (правильно ли задана спецификация?)   -  person Gangadhar    schedule 22.07.2012
comment
Я отредактировал пост и указал формат кодировки файла. Нет, вопрос не только в сортировке и слиянии, я дал более подробную информацию, относящуюся к тому, что я хочу знать. Да, сортировка, объединение и удаление дубликатов — это тоже то, что я хочу знать.   -  person Neon Flash    schedule 22.07.2012


Ответы (1)


Хм, я бы использовал

cat file1.txt file2.txt other-files.* | recode enc1..enc2 | sort | uniq > file3.txt 

но будьте осторожны - это может вызвать проблемы с некоторыми большими размерами файлов, исчисляемыми в гигабайтах (или больше), в любом случае с сотнями мегабайт, вероятно, все будет в порядке. Если бы я хотел реальной эффективности, например. имея действительно огромные файлы, я сначала удалял дубликаты одного файла, затем сортировал их, объединял один за другим, а затем снова сортировал и снова удалял повторяющиеся строки. Теоретически uniq -c и фильтр grep могут удалить дубликаты. Старайтесь не впадать в ненужную изощренность решения :)

http://catb.org/~esr/writings/unix-koans/two_paths.html

отредактировано:

mv file1.txt file1_iso1234.txt 
mv file2.txt file2_latin7.txt
ls file*.txt |while read line; do cat $line |recode $(echo $line|cut -d'_' -f2 |cut -d'.' -f1)..utf8 ; done | sort | uniq > finalfile.txt
person Ahk4iePaiv8u    schedule 22.07.2012
comment
Хорошо спасибо. В моем случае проблема с кодировкой обоих файлов. Итак, как мне использовать опцию перекодирования? Не могли бы вы уточнить это? Более того, моя команда выглядит точно так же, как и ваша, но все равно не удаляет дубликаты, в чем может быть причина? - person Neon Flash; 22.07.2012
comment
Конечно, вам нужно сортировать до uniq, и вам нужно, чтобы все входные данные были с одной и той же кодировкой, прежде чем вы сортируете. Итак, если файлы имеют разные кодировки, вам необходимо перекодировать их из подходящей в какую-то общую кодировку, которую вы решите использовать, возможно, utf8. Чтобы решить эту проблему быстро, вы можете переименовать файлы, чтобы они содержали кодировку в имени файла mv file1.txt file1_iso1234.txt mv file2.txt file2_latin7.txt, а затем, например, ls file*.txt |во время чтения строки; do cat $line |recode $(echo $line|cut -d'_' -f2 |cut -d'.' -f1)..utf8 | .. [конец так далее после трубы с sort, uniq и т. д.] что-то в этом роде.. - person Ahk4iePaiv8u; 22.07.2012
comment
Спасибо. Однако перекодирование недоступно в Cygwin. Я понял ваше решение, хотя. Я попытался преобразовать iconv из кодировки us_ascii в utf-8, и это выдало ошибку при разборе исходного файла. Я тоже попробую ваше решение. - person Neon Flash; 22.07.2012