Возможно, мне не повезло, потому что мой CSV-файл, разделенный запятыми, содержит и двойные кавычки, и запятые внутри полезного текста.
Итак, я хочу это превратить:
"record 1","name 1","text 1, text 2"
"record 2","name ""2""","text 2"
"record 3","name 3",""
на том:
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
Обратите внимание, что я удалил двойную кавычку из name ""2""
to name 2
, но сохранил двойную кавычку из строки №3:,""
решение1
Используем csvformat
для замены разделителей на символы табуляции ( csvformat -T
), удаляем все двойные кавычки ( tr -d '"'
), а затем возвращаем разделители на запятые, заключая в кавычки каждое поле (последний бит конвейера):
$ csvformat -T file.csv | tr -d '"' | csvformat -t -U1
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
csvformat
частьcsvkit
.
решение2
Это будет работать независимо от того, какие символы присутствуют во входных данных (за исключением символов новой строки в полях, заключенных в кавычки, но это уже совсем другая проблема).
С GNU awk для FPAT:
$ awk -v FPAT='("[^"]*")+' -v OFS='","' '{
for ( i=1; i<=NF; i++ ) {
gsub(/"/,"",$i)
}
print "\"" $0 "\""
}' file
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
или эквивалент с любым awk:
$ awk -v OFS='","' '{
orig=$0; $0=""; i=0;
while ( match(orig,/("[^"]*")+/) ) {
$(++i) = substr(orig,RSTART,RLENGTH)
gsub(/"/,"",$i)
orig = substr(orig,RSTART+RLENGTH)
}
print "\"" $0 "\""
}' file
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
Смотрите такжекакой-самый-надежный-способ-эффективно-разобрать-csv-с-помощью-awk.