Мое требование - добавить новые заголовки в существующий файл CSV, в первой строке которого уже есть несколько заголовков. Мне нужно добавить новые заголовки в конце существующих заголовков. Значение новых заголовков будет пустым; Мне просто нужно создать заголовок.
Например, ниже мой CSV-файл
Cust_Name,Cust_ADD
A1,CBD
A2,CBE
A3,CBE
Мне нужно добавить заголовки «зарплата, возраст» в конце файла CSV.
Я попробовал этот код
sed -i "1s|\$|,$new_headers|" input.csv
Это дает мне результат, как показано ниже
Cust_Name,Cust_ADD
,Salary,age
A1,CBD
A2,CBE
A3,CBE
Новые заголовки появляются во второй строке.
Ожидаемый результат
Cust_Name,Cust_ADD,salary,age
A1,CBD,,
A2,CBE,,
A3,CBE,,
С любым awk
% awk '{NR == 1 ? $0=$0",salary,age" : $0=$0",,"}1' file.csv
Cust_Name,Cust_ADD,salary,age
A1,CBD,,
A2,CBE,,
A3,CBE,,
% cat file.csv
Cust_Name,Cust_ADD
A1,CBD
A2,CBE
A3,CBE
Я все еще получаю новые заголовки во второй строке awk '{NR == 1 ? $0=$0",salary,age" : $0=$0",,"}1' input.csv > input.csv
Не следует перенаправляться на тот же файл. Используйте временный файл, например. awk '{NR == 1 ? $0=$0",salary,age" : $0=$0",,"}1' input.csv > input_mod.csv && mv input_mod.csv input.csv
Я попробовал это awk '{NR == 1 ? $0=$0",salary,age" : $0=$0",,"}1' input.csv > temp.csv && mv temp.csv input.csv новые заголовки идут во второй строке
Вы пробовали это с опубликованными данными? Там это работает? Как выглядит input.csv? Есть ли новая строка Windows в конце первой строки? См., например. stackoverflow.com/questions/19406418/…
это правильно, в конце первой строки появилась новая строка после ее удаления с помощью sed -i '1s/\r$//' input.csv. Я могу создать заголовки в первой строке, но в ней создана пустая строка конец каждой строки
Если в результате есть дополнительные данные, они, вероятно, уже присутствуют в исходном файле input.csv. Включите отображение пробелов или что-то подобное в вашем любимом редакторе и проверьте файл.
можно исправить это, используя awk 'NR == 1 { $0 = $0 ",Salary,age"}1' input.csv > temp.csv && mv temp.csv input.csv
Это может сработать для вас (GNU sed):
sed -i '1s/$/,salary,age/;1!s//,,/' file
В первой строке добавьте ,salary,age
.
Во всех остальных строках добавьте ,,
.
Н.Б. Вторая команда замены, поскольку она пуста, использует предыдущее регулярное выражение, но предоставляет новое значение для добавления, то есть s//,,/
.
У вас могут быть окончания строк DOS, см. Почему выходные данные моего инструмента перезаписывают себя и как это исправить?.
Как только это будет исправлено, если необходимо, используйте любой awk:
$ awk '{print $0 (NR>1 ? ",," : ",salary,age")}' file
Cust_Name,Cust_ADD,salary,age
A1,CBD,,
A2,CBE,,
A3,CBE,,
Дополнительную информацию о работе с CSV с помощью awk см. в разделе Какой самый надежный способ эффективного анализа CSV с помощью awk?.
Да, первое знакомство с dos2unix
и unix2dos
всегда будет хорошим советом. Хороший улов.
Я бы использовал GNU AWK
для этой задачи следующим образом: пусть file.csv
контент будет
Cust_Name,Cust_ADD
A1,CBD
A2,CBE
A3,CBE
затем
awk -v headers = "salary,age" 'BEGIN{FS=OFS = ","}NR==1{$0=$0 "," headers;fnum=NF}{NF=fnum;print}' file.csv
дает результат
Cust_Name,Cust_ADD,salary,age
A1,CBD,,
A2,CBE,,
A3,CBE,,
Объяснение: я ввожу headers
с помощью переключателя -v
(поэтому, если у вас есть заголовки в переменной оболочки с именем headers, вы можете сделать headers = "$headers"
) и сообщаю GNU AWK
, что запятая является одновременно разделителем полей (FS
) и разделителем выходных полей (OFS
), в 1-й строке я добавляю запятую и заголовки в строку и сохраните количество полей (NF
) в переменной fnum
. Для каждой переменной я установил количество полей равным fnum
, чтобы GNU AWK
добавил подходящее количество пустых полей и print
строку.
(проверено в GNU Awk 5.1.0)
Установка new_headers=salary,age
и запуск команды sed для предоставленных вами входных данных не приводит к предоставленному вами выводу. Таким образом, почти наверняка проблема со странным расположением новой строки возникает из-за чего-то, чего вы не показали.
Проверьте содержимое входного файла и переменной. Используйте что-то, что позволит вам видеть всех персонажей. Например:
sed -n "=;l;s|\$|,$new_headers|;l;q" input.csv
=
- вывести номер строкиl
— распечатать исходную строку в «визуально однозначном» видеs///
- выполнить заменуl
— вывести измененную строку в «визуально однозначном» видеq
— выйти (чтобы доказать, что обрабатывается только первая строка)
Что означает
declare -p new_headers
выходные данные; точнее, у тебя есть\n
в конце?