У меня есть CSV-файл с полем, содержащим данные, заключенные в " " и запятые между ними. Я хочу заменить его другим

В /etc/fstabвы можете попробовать добавить x-systemd.before=nfs-kernel-server.serviceкак опцию к монтировке, может быть?

1
13.03.2020, 13:24
7 ответов

Временно изменив разделитель CSV на@(или любой другой символ, который еще не является частью данных )с помощью csvformatиз csvkit, затем изменив соответствующие строки в 5-м поле с помощью awkи возврат разделителя к исходной запятой:

csvformat -D '@' data.csv |
awk 'BEGIN { OFS=FS="@" } $5 == "10,00,000.0" { $5 = "10,000,000.0" }; 1' |
csvformat -d '@'

С вашими данными в data.csvполучается:

DE000A2200V7,09:30:00,8.5,8.509,"10,000,000.0","10,00,000.0","850,450.0"
DE000A2200V7,11:30:00,8.7,8.709,"20,00,000.0","20,000.0","870,450.0"
DE000A2200V7,13:30:00,8.763,8.883,"30,00,000.0","20,000.0","882,300.0"
DE000A2200V7,15:30:00,8.481,8.501,"10,000,000.0","10,00,000.0","849,100.0"
DE000A2200W5,09:30:00,15.826,15.835,"20,000.0","20,000.0","1,583,050.0"
0
28.04.2021, 23:20

sed -i.backup 's/,"10,00,000.0"/,"10,000,000.0"/' data.csv

  1. -i.backupзаписать результат в исходный файл и сделать резервную копию исходных данных в data.csv.backup
  2. s/найти ,""10,00,000.0"и заменить /,"10,000,000.0"/только первое совпадение в строке
  3. data.csvфайл для продолжения
0
28.04.2021, 23:20

С GNUawk

awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '$5 == "\"10,00,000.0\"" \
{ $5="\"10,000,000.0\""}; {print}' file

Тесты

$ cat file
DE000A2200V7,09:30:00,8.5,8.509,"10,00,000.0","10,00,000.0","850,450.0"
DE000A2200V7,11:30:00,8.7,8.709,"20,00,000.0","20,000.0","870,450.0"
DE000A2200V7,13:30:00,8.763,8.883,"30,00,000.0","20,000.0","882,300.0"
DE000A2200V7,15:30:00,8.481,8.501,"10,00,000.0","10,00,000.0","849,100.0"
DE000A2200W5,09:30:00,15.826,15.835,"20,000.0","20,000.0","1,583,050.0"

$ awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '$5 == "\"10,00,000.0\"" { $5="\"10,000,000.0\""}; {print}' file
DE000A2200V7,09:30:00,8.5,8.509,10,000,000.0,"10,00,000.0","850,450.0"
DE000A2200V7,11:30:00,8.7,8.709,"20,00,000.0","20,000.0","870,450.0"
DE000A2200V7,13:30:00,8.763,8.883,"30,00,000.0","20,000.0","882,300.0"
DE000A2200V7,15:30:00,8.481,8.501,10,000,000.0,"10,00,000.0","849,100.0"
DE000A2200W5,09:30:00,15.826,15.835,"20,000.0","20,000.0","1,583,050.0"

Пояснение

-vFPAT='([^,]*)|("[^"]+")' 

разделяет поля запятыми, обрабатывая случаи, когда поля могут содержать встроенные запятые (см. руководство GNU awk Определение полей по содержимому).

-vOFS=,

указывает, что разделителем выходного файла является запятая ,.

'$5 == "\"10,00,000.0\"" { $5="\"10,000,000.0\""}; {print}'

если пятый столбец соответствует строке «10 00 000,0», заменить ее на «10 000 000,0»; напечатать строку.

-1
28.04.2021, 23:20

Вы можете сделать это с помощью следующей команды sed:

sed -i 's/^\(\([^,]*,\)\{4\}\)\("[^"]*"\)\(.*\)$/\1"10,000,000.0"\4/' data.csv
0
28.04.2021, 23:20

Уверены, что "20 00 000,0" верно? Если нет, попробуйте

sed 's/,00,/,000,/' file

Добавить флаг s's g, если нужно исправить все неправильные номера...

0
28.04.2021, 23:20

Просто разбейте и восстановите строки на ", установив FS=OFS="\""и протестировав второе поле

awk 'BEGIN{FS=OFS="\""} $2=="10,00,000.0"{$2="10,000,000.0"};1' file1
0
28.04.2021, 23:20

На тот случай, если настоящий вопрос:

How do the change to commas from grouping thousand, lakh and crore to grouping by thousands, millions, etc in the fields of a CSV file?

может быть, это подойдет, продолжая тот же трюк из другого ответа:

LC_ALL=en_US.UTF-8 awk -v RS='"' -v ORS= '{
  if(NR % 2){print}
  else if(/[^0-9.,]/){print RS $0 RS}
  else { gsub(/,/,""); printf RS "%'\''.1f" RS, $0}
}' file

DE000A2200V7,09:30:00,8.5,8.509,"1,000,000.0","1,000,000.0","850,450.0"
DE000A2200V7,11:30:00,8.7,8.709,"2,000,000.0","20,000.0","870,450.0"
DE000A2200V7,13:30:00,8.763,8.883,"3,000,000.0","20,000.0","882,300.0"
DE000A2200V7,15:30:00,8.481,8.501,"1,000,000.0","1,000,000.0","849,100.0"
DE000A2200W5,09:30:00,15.826,15.835,"20,000.0","20,000.0","1,583,050.0"

Предполагается, что awk поддерживает локали или не реализует сам себя printf(gawk, bwk,mawk)Томаса Дики. Стандартный awk от Debian (и старая версияmawk)НЕ подходят.

Требуется только LC_NUMERIC; LC_ALLиспользуется как лекарство от другого LC_ALL, который может присутствовать в окружающей среде;-)

0
28.04.2021, 23:20

Теги

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