Як уникнути подвійних та одинарних лапок у sed?


79

З того, що я можу знайти, коли ви використовуєте одинарні лапки, все всередині вважається буквальним. Я хочу це для своєї заміни. Але я також хочу знайти рядок, який має одинарні або подвійні лапки.

Наприклад,

sed -i 's/"http://www.fubar.com"/URL_FUBAR/g'

Я хочу замінити "http://www.fubar.com" на URL_FUBAR. Як sed повинен розпізнати мої // або мої подвійні лапки?

Дякуємо за будь-яку допомогу!

EDIT: Чи можу я використати s/\"http\:\/\/www\.fubar\.\com\"/URL_FUBAR/g?

Чи справді \ уникнути символів всередині окремих лапок?

Відповіді:


108

s///Команда в sedдозволяє використовувати інші символи , а не в /якості роздільника, як в

sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'

або

sed 's,"http://www\.fubar\.com",URL_FUBAR,g'

Подвійні лапки не є проблемою. Для відповідності одинарних лапок переключіть два типи лапок. Зверніть увагу, що один рядок із лапками не може містити одинарних лапок (навіть не екранованих).

Точок потрібно уникати sed, щоб інтерпретувати їх як буквальні крапки, а не як шаблон регулярного виразу, .який відповідає якомусь одному символу.


чудова відповідь dood, у мене просто швидке запитання. Як би я зробив одинарні лапки замість своїх пар. У моєму коді є екземпляри, коли він одиничний або подвійний, я можу просто виконати цю команду двічі, але який синтаксис для виходу з однієї лапки?
KRB

Уникнення одинарних лапок у мене не спрацювало (bash на mac), але використання різних типів лапок для обтікання команди, ніж замінена лапка, спрацювало. наприклад: sed 's/"/bla/g'замінити "на blaабо sed "s/'/bla/g" to replace `` withbla
rrr

1
@rrr Рядок із цитуваннями не може містити вбудовану одинарку. Зміна зовнішніх лапок (і уникнення будь-яких спеціальних символів, які тепер може бути зацікавлена ​​в інтерпретації оболонки) - це один із способів вирішити це. Інший варіант - вирватися з рядка з "'"одинарними лапками та об'єднати рядок з ( одинарна лапка з подвійними лапками), перш ніж продовжувати з рештою рядка з цитуваннями, як у 'you'"'"'d better do that'.
Кусалананда

30

Щодо одинарних лапок, див. Код нижче, який використовується для заміни рядка let'sна let us:

команда:

echo "hello, let's go"|sed 's/let'"'"'s/let us/g'

результат:

привіт, відпустимо


14

Моя проблема полягала в тому, що мені потрібно було мати ""зовнішній вираз, оскільки у мене є динамічна змінна всередині самого виразу sed. Отже, фактичним рішенням є рішення від Lenn Jackman, яким ви замінюєте "внутрішній регулярний вираз sed [\"].

Отже, мій повний Bash:

RELEASE_VERSION="0.6.6"

sed -i -e "s#value=[\"]trunk[\"]#value=\"tags/$RELEASE_VERSION\"#g" myfile.xml

Ось:

# є сепаратором седу

[\"] = "у регулярному виразі

value = \"tags/$RELEASE_VERSION\" = мій рядок заміни, важливо, що він має лише \"для лапок


13

Важко уникнути єдиної лапки в межах одинарних лапок. Спробуйте це:

sed "s@['\"]http://www.\([^.]\+).com['\"]@URL_\U\1@g" 

Приклад:

$ sed "s@['\"]http://www.\([^.]\+\).com['\"]@URL_\U\1@g" <<END
this is "http://www.fubar.com" and 'http://www.example.com' here
END

виробляє

this is URL_FUBAR and URL_EXAMPLE here

1

Уникнення подвійних лапок може бути абсолютно необхідним у sed: наприклад, якщо ви використовуєте подвійні лапки у всьому виразі sed (як це потрібно робити, коли ви хочете використовувати змінну оболонки).

Ось приклад, який торкається втечі в sed, але також описує деякі інші проблеми з цитуванням у bash:

# cat inventory
PURCHASED="2014-09-01"
SITE="Atlanta"
LOCATION="Room 154"

Скажімо, ви хотіли змінити кімнату, використовуючи скрипт sed, який ви можете використовувати знову і знову, тому ви варіюєте введення таким чином:

# i="Room 101" (these quotes are there so the variable can contains spaces)

Цей скрипт додасть цілий рядок, якщо його там немає, або він просто замінить (використовуючи sed) рядок, що знаходиться там, текстом плюс значення $ i.

if grep -q LOCATION inventory; then 
## The sed expression is double quoted to allow for variable expansion; 
## the literal quotes are both escaped with \ 
    sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory
## Note the three layers of quotes to get echo to expand the variable
## AND insert the literal quotes
else 
    echo LOCATION='"'$i'"' >> inventory
fi

PS Я написав наведений вище сценарій на декілька рядків, щоб зробити коментарі синтаксичним, але я використовую його як однорядковий рядок у командному рядку, який виглядає так:

i="your location"; if grep -q LOCATION inventory; then sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory; else echo LOCATION='"'$i'"' >> inventory; fi

1

Поряд: вирази sed, що містять змінні BASH, повинні бути в подвійних ( ") лапках, щоб змінна правильно інтерпретувалася.

Якщо ви також подвійно вводите свою змінну $ BASH (рекомендована практика)

... тоді ви можете уникнути змінних подвійних лапок, як показано:

sed -i "s/foo/bar ""$VARIABLE""/g" <file>

Тобто, замініть $ VARIABLE, пов'язану "з "".

(Просто -зміна, "$VAR"як \"$VAR\"результат у "вихідному рядку -процитованому.)


Приклади

$ VAR='apples and bananas'
$ echo $VAR
apples and bananas

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' $VAR
I like apples!
I like and!
I like bananas!

$ printf 'I like %s!\n' "$VAR"
I like apples and bananas!

Тут $ VAR "-цитується перед подачею трубопроводу до sed (sed або '- або "-quoted):

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/"$VAR"/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed 's/""$VAR""/cherries/g'
I like apples and bananas!

$ printf 'I like %s!\n' "$VAR" | sed "s/$VAR/cherries/g"
I like cherries!

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!

Порівняйте це з:

$ printf 'I like %s!\n' $VAR | sed "s/$VAR/cherries/g"
I like apples!
I like and!
I like bananas!


$ printf 'I like %s!\n' $VAR | sed "s/""$VAR""/cherries/g"
I like apples!
I like and!
I like bananas!

... і так далі ...

Висновок

Моя рекомендація, як звичайна практика, - це

  • "-цитувати змінні BASH ( "$VAR")
  • "-процитуйте, знову ж таки , ті змінні ( ""$VAR""), якщо вони використовуються у виразі sed (який сам повинен бути "-процитованим, а не '-процитованим)
$ VAR='apples and bananas'

$ echo "$VAR"
apples and bananas

$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!


0
Prompt% cat t1
This is "Unix"
This is "Unix sed"
Prompt% sed -i 's/\"Unix\"/\"Linux\"/g' t1
Prompt% sed -i 's/\"Unix sed\"/\"Linux SED\"/g' t1
Prompt% cat t1
This is "Linux"
This is "Linux SED"
Prompt%

Просто використовуйте (зворотну скісну риску) перед "(подвійні лапки) .. і використовуйте параметр -i
SachinH

1
Хоча цей фрагмент коду вітається і може надати певну допомогу, його було б значно покращено, якби він містив пояснення того, як він вирішує питання. Без цього ваша відповідь має набагато меншу освітню цінність - пам’ятайте, що ви відповідаєте на запитання читачам у майбутньому, а не лише тому, хто запитує зараз! Будь ласка, відредагуйте свою відповідь, щоб додати пояснення, та вкажіть, які обмеження та припущення застосовуються.
Toby Speight


-4

Вам потрібно використовувати символ \ "для екранування" (\ escape наступного символу

sed -i 's/\"http://www.fubar.com\"/URL_FUBAR/g'

-7

Може бути символ "\", спробуйте це:

sed 's/\"http:\/\/www.fubar.com\"/URL_FUBAR/g'

4
пропонування дикої здогадки не є рішенням. ви можете замість цього додати такі здогади в коментарях - або навіть краще - спробувати спершу
SeriousM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.