У меня есть данные в следующем формате:

"1";"abc"
"2";"dfg"
"3";"hij"

Я использовал следующую команду для добавления столбца:

sed "s/$/;"newc"/" file.csv

но я получаю последний столбец без кавычек:

"1";"abc";newc
"2";"dfg";newc
"3";"hij";newc

Не могу понять, как его обновить, добавить двойные кавычки и получить:

"1";"abc";"newc"
"2";"dfg";"newc"
"3";"hij";"newc"

1 ответ1

0

Проблема была решена в комментариях без должного объяснения:

Окружающий скрипт с одинарными кавычками не работает? 's/$/;"newc"/'

да, это сработало!

Этот ответ поможет пролить свет на то, что произошло и почему решение работает.


В вашей оригинальной команде цитирование выглядит так:

sed "s/$/;"newc"/" file.csv
#   ^     ^        a matching pair of quotes
#              ^ ^ another pair of quotes
#    s/$/;      /  these fragments are quoted
#          newc    this fragment is not quoted at all

Цитаты, которые вы использовали, потребляются оболочкой. Их присутствие указывает оболочке обрабатывать строки в кавычках несколько иначе, чем строки в кавычках, например, точка с запятой в кавычках (;) не является разделителем команд; затем они исчезают, т.е. оболочка не передает их в sed .

Обратите внимание, что newc содержит специальных символов для оболочки, он ведет себя одинаково, независимо от того, указан он в кавычках или нет. Это означает, что newc может быть заключен в кавычки, вот так:

sed "s/$/;""newc""/" file.csv
#          ^    ^    added pair of quotes

Но это эквивалентно

sed "s/$/;newc/" file.csv

и после того, как оболочка потребит, кавычки sed получат следующие аргументы: s/$/;newc/ , file.csv . Как видите, инструмент вообще не получает кавычек.

Чтобы передать кавычки в sed вам нужно сделать так, чтобы они "выживали" при разборе, выполняемом оболочкой. Есть несколько способов сделать это. Два общих подхода:

  1. Спасаясь с \ . Внутри двойных кавычек вы можете экранировать символ двойной кавычки, поэтому он рассматривается как часть строки в кавычках, а не как заключительная кавычка. В твоем случае:

    sed "s/$/;\"newc\"/" file.csv
    
  2. Смешивание цитат. Двойная кавычка внутри одинарных кавычек остается. Упомянутое решение использует этот факт:

    sed 's/$/;"newc"/' file.csv
    

    Одинарная кавычка внутри двойных кавычек также остается. Например, если вам нужно передать буквальный аргумент '" в echo , это сработает:

    echo "'"'"'
    #    ^ ^    # a pair of double quotes that make the single quote survive
    #       ^ ^ # a pair of single quotes that make the double quote survive
    

Иногда полезно вызвать set -x перед командой "неправильного поведения", чтобы узнать, что осталось после того, как оболочка проанализирует его. Ваша оригинальная команда и две фиксированные генерируют это (вывод от sed опущен для ясности):

$ sed "s/$/;"newc"/" file.csv       # original command
+ sed s/$/;newc/ file.csv
$ # the above line contains what sed really got
$ sed "s/$/;\"newc\"/" file.csv     # fixed
+ sed s/$/;"newc"/ file.csv
$ # this time sed got the right string
$ sed 's/$/;"newc"/' file.csv       # also fixed
+ sed s/$/;"newc"/ file.csv
$ # again the right string
$ 

Примечание: в конце вызовите set +x чтобы вернуться к тому, что сделал set -x .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .