замените CR LF в текстовом файле, используя `sed` или` fart` (найти и заменить текст) - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть текстовый файл Windows объемом 1,5 ГБ, некоторые строки которого заканчиваются на LF , а большинство строк заканчиваются на CR + LF

Не могли бы вы помочь с sed скрипт, который

  • заменит все CR + LF на $ | $
  • заменит все LF с CR + LF
  • заменить обратно все $ | $ на CR + LF

Я пробовалвыполнить все замены в текстовом редакторе, но все замены файла заняли очень много времени (1 процент за полчаса).Я пытался заменить его на fart:

fart -c -B -b text.txt "\r\n" "$|$"

со следующим результатом

replacement 0 occurence(s) in 0 file(s)..

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Я бы сделал это: сначала удалите все \r в конце строки, а затем явно добавьте \r в конец строки.

sed -e 's/\r$//' -e 's/$/\r/' file

Вот демонстрационная версия:

$ printf "1\r\n2\n3\n4\r\n5\n" > file
$ od -c file
0000000   1  \r  \n   2  \n   3  \n   4  \r  \n   5  \n
0000014
$ sed -i -e 's/\r$//' -e 's/$/\r/' file
$ od -c file
0000000   1  \r  \n   2  \r  \n   3  \r  \n   4  \r  \n   5  \r  \n
0000017

Это GNU sed.

0 голосов
/ 10 февраля 2019

Проще просто установить утилиту , например unix2dos, которая делает это автоматически.При unix2dos предлагаемый промежуточный этап преобразования CR + LF в $ | $ (и обратно) не требуется.Демонстрация:

# first dump a file with both *DOS* and *Unix* style line endings:
hexdump -C <({ seq 2 | unix2dos ; seq 3 4; } )
# the same file, run through unix2dos
hexdump -C <({ seq 2 | unix2dos ; seq 3 4; } | unix2dos)

Вывод:

00000000  31 0d 0a 32 0d 0a 33 0a  34 0a                    |1..2..3.4.|
0000000a
00000000  31 0d 0a 32 0d 0a 33 0d  0a 34 0d 0a              |1..2..3..4..|
0000000c

Или более детально, таблица до / после (подробности форматирования см. man hexdump):

hdf() { hexdump -v  -e '/1  "%_ad#  "' -e '/1 " _%_u\_\n"' $@ ; }
# Note: the `printf` stuff keeps `paste` from misaligning the output.
paste <(hdf <({ seq 2 | unix2dos ; seq 3 4; }) ; printf '\t\n\t\n' ; ) \
      <(hdf <({ seq 2 | unix2dos ; seq 3 4; } | unix2dos ))

Вывод:

0#   _1_    0#   _1_
1#   _cr_   1#   _cr_
2#   _lf_   2#   _lf_
3#   _2_    3#   _2_
4#   _cr_   4#   _cr_
5#   _lf_   5#   _lf_
6#   _3_    6#   _3_
7#   _lf_   7#   _cr_
8#   _4_    8#   _lf_
9#   _lf_   9#   _4_
            10#  _cr_
            11#  _lf_
0 голосов
/ 08 февраля 2019

Один с awk:

$ awk '{sub(/(^|[^\r])$/,"&\r")}1' file

Тестирование (0x0a - LF, 0x0d - CR):

$ awk 'BEGIN{print "no\nyes\r\n\n\r"}' > foo
$ hexdump -C foo
00000000  6e 6f 0a 79 65 73 0d 0a  0a 0d 0a                 |no.yes.....|
0000000b
$ awk '{sub(/(^|[^\r])$/,"&\r")}1' foo > bar
$ hexdump -C bar
00000000  6e 6f 0d 0a 79 65 73 0d  0a 0d 0a 0d 0a           |no..yes......|
0000000d
...