Удаление символа новой строки из столбца в файле CSV

sed 's/:/ /2'

Это изменит второй символ :на пробел.

Вы можете вставить это как дополнительную стадию конвейера вашей функции:

#!/bin/sh

git rev-list --all |
while read revision; do
    git grep -F "$1" "$revision"
done |
sed 's/:/ /2'

(На самом деле я удалил эту функцию, так как она оказалась ненужной; обратите внимание также на цитирование расширений переменных; о, и это скрипт /bin/sh, поскольку он не использует никакихbash-специфических функций (, как и ваш, за исключением ненужного ключевого слова function))

1
22.09.2021, 11:47
5 ответов

Один из простых способов — просто удалить символы новой строки в строках, содержащих только 3 поля.:

$ perl -F','  -pane 's/\n// if $#F==2' file 
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,"ffadsdasd",01-09-2021

Конечно, это предполагает, что внутри поля никогда не может быть ,, что разрешено в CSV-файлах. Поэтому, если ваше поле Messageсодержит что-то вроде """foo,bar""", это может привести к ошибке. Вот почему всегда лучше использовать специальный парсер.

Этот подход должен работать для любого допустимого файла CSV:

$ perl -MText::CSV -le '$csv = Text::CSV->new({binary=>1}); while ($row = $csv->getline(STDIN)){ $row->[2]=~s/\n//; $csv->print(STDOUT,$row)}' < file
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,ffadsdasd,01-09-2021
2
22.09.2021, 12:46

Если у вас есть csvkitутилиты, вы можете исправить строки со встроенными символами новой строки, например, преобразовав новую строку в буквальные два символа\n:

csvformat -M $'\r' datafile |                    # temporarily end lines with $'\r'
    sed -e ':a' -e 'N;$!ba' -e 's/\n/\\n/g' |    # transform $'\n' into '\n'
    tr '\r' '\n'                                 # convert the line endings back to $'\n'

Спасибо плакату на csvkit github за их решение ,который, в свою очередь, ссылается на ответ на StackOverflow

2
22.09.2021, 13:08

Если ваш CSV-файл был сгенерирован средствами MS, такими как Excel, то «новая строка» в середине поля — это только LF, а «новая строка» в конце каждой записи — это CRLF, как здесь (обратите внимание на LF $среднее -поле против CRLF ^M$в конце записи):

$ cat -Ev file
ID,Code,Message,date^M$
1244,,"""Exception error : java connection error$
:8080 Connection refused""",01-09-2021^M$

и, если это так, вы можете просто сказать GNU awk (для multi -char RS ), что записи заканчиваются на CRLF, и заменить средние -записи LF пробелами:

$ awk -v RS='\r\n' '{gsub(/\n/," ")} 1' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021

Если у вас есть только POSIX awk и нет инструментов, которые работают с CSV, см. что -самый -самый -надежный -способ -к -эффективно -проанализируйте -csv -с помощью -awk , чтобы узнать, как с ними обращаться, или если CR больше нигде в вашем файле не появляется, вы можете сделать это с помощью любого awk:

$ awk -v RS='\r' 'NR>1{print prev} {sub(/^\n/,""); gsub(/\n/," "); prev=$0}' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021
2
22.09.2021, 13:21

Использование Raku (, ранее известного как Perl _6)

raku -MText::CSV -e 'my $csv=Text::CSV.new; .perl.put for $csv.getline_all(open($*ARGFILES, :r, :!chomp));'

Пример ввода:

ID,Code,Message,date
1244,,"""Exception error : java connection error
:8080 Connection refused""",01-09-2021

Пример вывода:

$["ID", "Code", "Message", "date"]
$["1244", "", "\"Exception error : java connection error\n:8080 Connection refused\"", "01-09-2021"]

Вы можете добиться того, на что надеетесь, используя специальный модуль (, например.Text::CSV)и язык программирования Raku. Я добавил вызов .perl, чтобы вы могли визуализировать символ \n(К вашему сведению, .rakuтакже работает ). Как только вы получите приведенную выше структуру данных, достаточно просто изменить код, сопоставив его с полями, чтобы исключить встроенные символы новой строки :

.
raku -MText::CSV -e 'my $csv=Text::CSV.new; .put for $csv.getline_all(open($*ARGFILES, :r, :!chomp)).map(*.subst("\n"," ", :g));'

Обновлен вывод:

ID Code Message date
1244  "Exception error : java connection error :8080 Connection refused" 01-09-2021

https://modules.raku.org/dist/Text::CSV:cpan:HMBRAND
https://github.com/Tux/CSV
https://raku.org

1
23.09.2021, 18:04

В качестве первого шага запустите файл CSV и преобразуйте его в окончания строк Unix:

dos2unix your_csvfile

Это изменяет \r\nна \n. Затем на следующем шаге:

Используя GNU sed, мы отслеживаем четное/нечетное количество двойных кавычек, как показано здесь:

sed -Ee '
  h;s/[^"]*//g
  /^(..)*$/!{
    z;G;N;D
  }
  g;s/\n//g
' your_csvfile

perl -pe 's/\n/<>/e while y/"// % 2' your_csvfile

Мы можем использовать утилиту awk для подсчета количества двойных кавычек и продолжать накапливать строки, пока они не станут четными.

awk '{
  t = $0
  while ((gsub(/"/,"&",t) ~ /[13579]$/) && (getline nxt > 0)) 
    t = t nxt
  print t
}' your_csvfile

Выход:

     1  ID,Code,Message,date$
     2  1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021$
0
25.09.2021, 04:16

Теги

Похожие вопросы