Разлитый Linux текстовый файл по количеству строк сохраняет разрывы строк на месте - PullRequest
0 голосов
/ 09 мая 2018

Я новичок в Linux (не на своем собственном сервере) и хочу разделить некоторые текстовые файлы Windows, вызвав скрипт bash из стороннего приложения:

Пока у меня это работает двумя способами до определенного момента:

split -l 5000 LargeFile.txt SmallFile

for file in LargeFile.*
do
    mv "$file" "$file.txt"
done

awk '{filename = "wrd." int((NR-1)/5000) ".txt"; print >> filename}' LargeFile.txt

Но оба дают мне текстовые файлы с результатом:

line1line2line3line4

Я нашел несколько тем о том, как поместить LargeFile.txt в подобный $ (LargeFile.txt), но он не работает для меня. (Также я нашел swich, позволяющий команде split создавать текстовые файлы напрямую, но это также не работает)

Я надеюсь, что кто-нибудь может помочь мне в этом.

1 Ответ

0 голосов
/ 14 мая 2018

Пояснение: терминаторы линии

Как объясняется различными ответами на этот вопрос , стандартные терминаторы строки различаются в разных ОС:

  • Linux использует LF (перевод строки, 0x0a)
  • Windows использует CRLF (возврат каретки и перевод строки 0x0d 0x0a)
  • Mac, до OS X используется CR (возврат каретки CR)

Чтобы решить вашу проблему, важно выяснить, какие терминаторы строки использует ваш LargeFile.txt. Простейшим способом будет команда file:

file LargeFile.txt

Выходные данные будут указывать, являются ли терминаторы строки CR или CRLF, а в противном случае просто указывают, что это ASCII-файл.

Поскольку в Linux терминаторы строк LF и CRLF будут правильно распознаваться, и строки не должны отображаться объединенными (независимо от того, какой способ вы используете для просмотра файла), если вы не настроите редактор специально для них, поэтому будет предполагать, что ваш файл имеет CR ограничителей строки.

Пример решения вашей проблемы (при условии CR ограничителей строки)

Если вы хотите разделить файл в оболочке и с помощью команд оболочки, вы потенциально столкнетесь с проблемой, заключающейся в том, что такие как cat, split, awk и т. Д. Не будут распознавать окончания строк в первую очередь , Если ваш файл очень большой, это может привести к проблемам с памятью (?).

Таким образом, лучший способ справиться с этим может состоять в том, чтобы сначала перевести терминаторы строки (используя команду tr), чтобы они понимались в Linux (т. Е. LF), а затем применить split или awk код перед переводом ограничителей строки назад (если вы считаете, что вам нужно это сделать).

cat LargeFile.txt | tr "\r" "\n" > temporary_file.txt
split -l 5000 temporary_file.txt SmallFile
rm temporary_file.txt
for file in `ls SmallFile*`; do filex=$file.txt; cat $file | tr "\n" "\r" > $filex; rm $file; done

Обратите внимание, что последняя строка на самом деле является циклом for:

for file in `ls SmallFile*` 
do 
    filex=$file.txt 
    cat $file | tr "\n" "\r" > $filex
    rm $file
done

В этом цикле снова будет использоваться tr для восстановления ограничителей строки CR и, кроме того, полученным файлам будет txt окончание имени файла.

Некоторые замечания

Конечно, если вы хотите сохранить терминаторы строки LF, вам не следует выполнять эту строку.

И, наконец, если вы обнаружите, что у вас есть другой тип терминаторов строки, вам может понадобиться адаптировать команду tr в первой строке.

Оба tr и split (а также cat и rm) являются частью GNU coreutils и должны быть установлены в вашей системе, если вы не находитесь в очень нетипичной среде ( возможно, спасение оболочки исходного RAM-диска). То же самое (обычно должно быть доступно) относится к команде file, к этой .

...