Обновите CSV-файл, используя bash - PullRequest
0 голосов
/ 17 марта 2020

У меня есть CSV-файл с именем ученика и оценками. Я хочу обновить «оценки» студента с именем «Джек» (единственный человек в CSV). данные в csv-файле выглядят следующим образом.

student,marks
jack,10
peter,20
rick,10

Я нашел этот awk '$ 1 == "Audrey" {print $ 2}' numbers.txt, но я не уверен, как изменить файл.

Ответы [ 5 ]

2 голосов
/ 18 марта 2020
awk 'BEGIN{FS=OFS=","} $1=="jack"{$2=27} 1' foo.csv > tmp && mv tmp foo.csv
1 голос
/ 18 марта 2020

ed обычно лучше для редактирования файлов на месте, чем sed:

printf "%s\n" "/^jack,/c" "jack,${new_grade}" "." w | ed -s input.csv

или с использованием heredo c для облегчения чтения:

ed -s input.csv <<EOF
/^jack,/c
jack,${new_grade}
.
w
EOF

В первой строке, начинающейся с jack,, c передать его jack,XX, где XX - значение переменной new_grade и w Записать новое содержимое файла.

0 голосов
/ 18 марта 2020

Другой подход с sed состоит в том, чтобы привязать замену к цифрам в конце строки с помощью:

sed '/^jack,/s/[0-9][0-9]*$/12/' file

При этом используется форма sed '/find/s/match/replace', где find находится в начале строка '^' слово "jack," устраняет всю двусмысленность, например, jackson,33. Затем нормальная замена форма 's/match/replace/', где match находит хотя бы один ди git в конце строки (привязанный '$') и заменяет его на 12 (или что бы вы ни выбрали).

Пример использования / Вывод

С вашим файлом примера в file вы получите:

$ sed '/^jack,/s/[0-9][0-9]*$/12/' file
student,marks
jack,12
peter,20
rick,10

( примечание: класс символов POSIX [[:digit:]] эквивалентен [0-9], что является другой альтернативой)

Эквивалентное выражение с использованием класса символов POSIX будет:

sed '/^jack,/s/[[:digit:]][[:digit:]]*$/12/' file

Вы также можете использовать Расширенное регулярное выражение , которое предоставляет оператор повторения '+' для указания один или несколько по сравнению с базовым c указателем повторения '*' указать ноль или более . Эквивалентный ERE будет sed -E '/^jack,/s/[0-9]+$/12/' file

. Вы можете добавить опцию -i для редактирования на месте и / или использовать ее как -i.bak, чтобы создать резервную копию оригинала с расширением .bak перед изменение оригинала.

0 голосов
/ 18 марта 2020

У меня это работало с

sed -ir "s/^\(jack\),.*/\1,$new_grade/" 

input.csv. с аргументом "r", иначе я получаю " error sed: 1:" input.csv ": ожидаемая команда \, за которой следует текст ".

0 голосов
/ 17 марта 2020

Вы можете использовать sed:

new_grade=9
sed -i'' "s/^\(jack\),.*/\1,$new_grade/"

Шаблон ^\(jack\),.* соответствует началу строки ^, за которой следует jack запятой и остальная часть строки .*. Строка замены \1,$new_mark содержит первую захваченную группу \1 (в данном случае jack), за которой следуют запятая и новая отметка.

В качестве альтернативы вы можете l oop над файлом и использовать замена шаблона:

new_grade=9
while read -s line; do
    echo ${line/jack,*/jack,$new_grade}
done < grades.txt > grades2.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...