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
))
Один из простых способов — просто удалить символы новой строки в строках, содержащих только 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
Если у вас есть 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
Если ваш 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
Использование 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
В качестве первого шага запустите файл 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$