sed заменить символ новой строки внутри каждой строки - PullRequest
2 голосов
/ 04 августа 2020

У меня есть огромный файл csv из экспорта, разделенного вертикальной чертой

8CDAC2EF-9261-4B9F-9D41-87B460C467B0|SAMPLE1|SAMPLE 2|SAMPLE 3|2020-08-03 00:00:00
8CDAC2EF-9261-4B9F-9D41-87B460C467B0|SAMPLE1|SAMPLE 

2|SAMPLE 3|2020-08-03 00:00:00
8CDAC2EF-9261-4B9F-9D41-87B460C467B0|SAMPLE1|SAMPLE 2|

|2020-08-03 00:00:00
8CDAC2EF-9261-4B9F-9D41-87B460C467B0|SAMPLE1|SAMPLE 2||2020-08-03 00:00:00
8CDAC2EF-9261-4B9F-9D41-87B460C467B0|SAMPLE1||SAMPLE 3|2020-08-03 00:00:00

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

PS: SAMPLE 2 и SAMPLE 3 также могут быть нулевыми.

Я хотел сделать это в формате ниже, ie, двойные кавычки заключены, как показано ниже.

"8CDAC2EF-9261-4B9F-9D41-87B460C467B0"|"SAMPLE1"|"SAMPLE 2"|"SAMPLE 3"|"2020-08-03 00:00:00"

Я попробовал приведенный ниже код, он работает нормально, но ломается, если есть новые символы строки в каждой строке.

sed  -e 's/^\|$/"/g' -e 's/|/"|"/g'  input.csv

Изменить: принятое решение работает нормально, но поскольку у меня есть какие-то необработанные данные, мне пришлось выполнить некоторые дополнительные шаги, поскольку некоторые из значений содержат | и другие специальные строки, которых там быть не должно.

То, что я сделал, было следующим.

  1. Мне удалось управлять разделителем из экспорта, я использовал , так как мы находим что он не используется в данных ни в одном из наших примеров.
  2. Затем я заменил ", ', | символом пробела. наконец, разделитель был заменен на |.
  3. Затем использовал принятый ответ, чтобы отфильтровать разрывы строк
  4. Наконец, передал их по конвейеру, чтобы они были заключены в кавычки.

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

Perl спешит на помощь!

perl -pe '$c += tr/|//; if ($c == 4) { $c = 0 } else { chomp }' -- file.csv
  • -p читает строку за строкой, печатает каждую строку после запуска кода
  • tr/// обычно используется для транслитерации, но здесь это просто быстрый метод подсчета количества вертикальных полос на текущей строке. Мы добавляем счетчик к переменной $c.
  • Если $c равно четырем, строка завершена, поэтому мы очищаем переменную.
  • если $c не четыре, строка еще не завершена (она также может быть слишком длинной, если данные неверны, но давайте сейчас это проигнорируем). Итак, мы запускаем chomp , чтобы удалить новую строку.
1 голос
/ 05 августа 2020

С sed:

sed '
    :a
    /\([^|]*|\)\{4\}/!{
      N
      s/\n//
      ba
   }' input.csv
...