Как добавить префикс для каждой строки определенного столбца в файле CSV через командную строку в Linux

Я пытаюсь добиться следующего.

Файл перед редактированием.

column-1,  column-2,  column-3,  column-4,  column-5
Row-1-c1,  Row-1-c2,  Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Row-5-c3,  Row-5-c4,  Row-5-c5

Файл после редактирования

column-1,   column-2,   column-3,           column-4,   column-5
Row-1-c1,   Row-1-c2,   Prefix-Row-1-c3,    Row-1-c4,   Row-1-c5
Row-2-c1,   Row-2-c2,   Prefix-Row-2-c3,    Row-2-c4,   Row-2-c5
Row-3-c1,   Row-3-c2,   Prefix-Row-3-c3,    Row-3-c4,   Row-3-c5
Row-4-c1,   Row-4-c2,   Prefix-Row-4-c3,    Row-4-c4,   Row-4-c5
Row-5-c1,   Row-5-c2,   Prefix-Row-5-c3,    Row-5-c4,   Row-5-c5

Обратите внимание, что column-3 - это столбец, в который префикс добавляется к каждой отдельной строке, кроме заголовка столбца. Мне было интересно, какой редактор будет лучшим редактором для использования и выяснил, как использовать команды, чтобы получить желаемый результат.

1 ответ

Возможно, лучшим вопросом будет "Сколько разных инструментов вы могли бы использовать для работы?"

Я бы наверное пошел с awk как самый простой инструмент, который делает работу достаточно просто:

awk -F, 'NR == 1 { print; OFS="," } NR > 1 { sub(/^ +/, "&Prefix-", $3); print }'

sub операция добавляет Prefix- после пробелов в начале столбца 3. Код не пытается корректировать содержимое строки 1 (заголовок); если вы хотите добавить пробелы после $3, тогда я полагаю, что это делает работу (из-за размещения запятых вы добавляете дополнительные пробелы к столбцу 4 строки 1):

awk -F, 'NR == 1 { OFS=","; $4 = "       " $4; print }
         NR  > 1 { sub(/^ +/, "&Prefix-", $3); print }'

Вы знаете, как сделать то же самое с sed?

Да, вот так:

sed -e '  1s/^\(\([^,]*,[[:space:]]*\)\{3\}\)/\1       /' \
    -e '2,$s/^\(\([^,]*,[[:space:]]*\)\{2\}\)/\1Prefix-/' "$@"

Первое выражение имеет дело с первой строкой; он ставит столько пробелов, сколько есть в префиксе (здесь это "Prefix-"так что это 7 пробелов) после третьего столбца. Второе выражение имеет дело с оставшимися строками; оно добавляет префикс перед третьим столбцом.

Чтобы иметь дело со столбцом N вместо столбца 3, измените 3 на N и 2 внутри \{2\} до N-1.

Я перепроверил второй скрипт Awk; он дает правильный вывод для меня на примере данных из вопроса. Итак, в рамках своих ограничений, делает первый скрипт Awk. Убедитесь, что вы используете что-то отличное от оболочки C (это расстраивается из-за многострочных строк в кавычках), и что вы были осторожны при копировании.

Пример вывода

$ cat data
column-1,  column-2,  column-3,  column-4,  column-5
Row-1-c1,  Row-1-c2,  Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Row-5-c3,  Row-5-c4,  Row-5-c5
$ bash manglesed.sh data
column-1,  column-2,  column-3,         column-4,  column-5
Row-1-c1,  Row-1-c2,  Prefix-Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Prefix-Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Prefix-Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Prefix-Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Prefix-Row-5-c3,  Row-5-c4,  Row-5-c5
$ bash mangleawk.sh data
column-1,  column-2,  column-3,         column-4,  column-5
Row-1-c1,  Row-1-c2,  Prefix-Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Prefix-Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Prefix-Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Prefix-Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Prefix-Row-5-c3,  Row-5-c4,  Row-5-c5
$ cat manglesed.sh
sed -e '  1s/^\(\([^,]*,[[:space:]]*\)\{3\}\)/\1       /' \
    -e '2,$s/^\(\([^,]*,[[:space:]]*\)\{2\}\)/\1Prefix-/' "$@"
$ cat mangleawk.sh
awk -F, 'NR == 1 { OFS=","; $4 = "       " $4; print }
         NR  > 1 { sub(/^ +/, "&Prefix-", $3); print }' "$@"
$ awk -F, 'NR == 1 { print; OFS="," } NR > 1 { sub(/^ +/, "&Prefix-", $3); print }' data
column-1,  column-2,  column-3,  column-4,  column-5
Row-1-c1,  Row-1-c2,  Prefix-Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Prefix-Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Prefix-Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Prefix-Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Prefix-Row-5-c3,  Row-5-c4,  Row-5-c5
$
Другие вопросы по тегам