sed: Как заменить переменную строку, если она найдена, или добавить в конец файла, если она не найдена?

494
Wade S

Так что мой вопрос в значительной степени основан на связанном вопросе, но имеет одно ключевое отличие.

В ответе дано:

sed '/^FOOBAR=/;$;x}' infile 

Я сделал вариант, который работает для того, чтобы сделать FOOBAR переменной (например, имя программы, а затем поместить ее в цикл for, чтобы составить список программ и их статус установки). Это довольно сложный проект, над которым я работаю, чтобы упростить установку Drawile для Raspberry Pi с некоторыми новыми функциями, но это другая червя, в которую я не буду вдаваться .

sed -i '/^'"$FOOBAR"'=/;$;x}' infile 

Я хотел бы, чтобы newvalue был переменной $, которая может измениться в скрипте. Я просто не могу понять, как заставить это работать, просто используя «и» делает это неправильно. Я провел часы, просматривая и пытаясь прочитать учебные пособия, но я просто не понимаю достаточно и глубоко погрузился в это. во внутреннюю работу sed. Большую часть времени эта переменная будет выглядеть так: да, нет или ошибка. Однако я также могу использовать ее для представления путей к папкам и файлам ... поэтому я беспокоюсь о / здесь также есть и замены. Даже если это не полный ответ, я с удовольствием пойму это сам, если смогу указать направление, в котором мне нужно лучше понять это.


Изменить: не так много, чтобы опубликовать, учитывая, что есть что-то фундаментальное, я уверен, что мне не хватает, я только что попробовал варианты размещения кавычек вокруг нового значения. Такие, как следует ...

sed -i '/^FOOBAR=/;$;x}' infile 

Вывод: FOOBAR = $ newvalue Это неверно. Должен вывести сохраненное значение для нового значения!

sed -i '/^FOOBAR=/;$;x}' infile 

Вывод: FOOBAR = "$ newvalue" Это неверно. Должен вывести сохраненное значение для нового значения!

sed -i '/^FOOBAR=/;$;x}' infile 

Вывод: sed: -e выражение # 1, char 30: неизвестная опция для `s '

Если newvalue равно Yes, то я бы хотел, чтобы вывод был «FOOBAR = Yes» или, возможно, путь к папке.


Изменить 2: Это может быть что угодно, на самом деле, при условии, что это просто работает. Я не особо разбираюсь в этом, но у меня, наверное, больше всего опыта с использованием sed, так что это то, на что я продолжаю смотреть ...


Изменить 3: нашел ответ.

sed -i '\!^'"$FOOBAR"'=!;$;x}' /home/pi/Public/test.txt 
1
«просто использование` '`и` "` не делает это правильно "- пожалуйста, отправьте команду, которая делает это неправильно, чтобы мы могли отладить. Kamil Maciorowski 6 лет назад 0
[Должно ли это быть `sed`?] (Https://en.wikipedia.org/wiki/Turing_tarpit) Было бы намного проще, например, с помощью perl или awk, или даже тщательно комбинированных встроенных оболочек. grawity 6 лет назад 0
Я думаю, что вариант с `'" $ newvalue "'` должен работать, если только `$ newvalue` не изменяет логику` sed`. Если, например, он содержит `/`, тогда выберите другой символ в качестве разделителя для `sed`. `sed 's / a / b /'` может быть `sed 's | a | b |'` или даже `sed 'sRaRbR'`. Выберите символ, который не сталкивается с возможным `$ newvalue`. Kamil Maciorowski 6 лет назад 1
Это не так. Он выводит $ newvalue, а не значение, хранящееся в переменной. Это не желаемый результат. Wade S 6 лет назад 0
Я говорю о варианте, который дает вам «неизвестную опцию» s. Попробуйте это с `$ newvalue`, который не содержит` / `. Kamil Maciorowski 6 лет назад 0
Вместо того, чтобы смешивать одинарные и двойные кавычки, я бы посоветовал проще использовать исходную замену только с двойными кавычками и экранировать (`\ $`) конец строки / ссылки на последнюю строку: `sed" / ^ $ FOOBAR = / ; \ $ , х} "`. Но имейте в виду комментарий @ KamilMaciorowski к `/` в `$ newvalue`, что означает, что вам, возможно, потребуется изменить разделитель. AFH 6 лет назад 0
Я просто получаю новые проблемы, когда делаю это (* sed: -e выражение # 1, char 1: неизвестная команда: `| '*). Я пытался поменять разделитель безуспешно. И простой выбор опции, которая не содержит / не является действительно опцией, учитывая то, что я пытаюсь заставить скрипт сделать. Wade S 6 лет назад 0
Если вы используете другой разделитель в адресе, вы должны экранировать первый `sed \ | ^ FOOBAR = | ... etc`. В `s` команда escape не нужна. Paulo 6 лет назад 0
Ах, я думаю, что я нашел решение с помощью всех, кто направил меня туда. Что я искренне ценю. `sed -i '\! ^'" $ FOOBAR "'=! ; $ ; x}' / home / pi / Public / test.txt` Wade S 6 лет назад 0
Ответ должен быть опубликован как ответ. См. [Могу ли я ответить на свой вопрос?] (Https://superuser.com/help/self-answer). Единственная команда (без каких-либо объяснений, в чем на самом деле была проблема и что именно делает исправление), была бы довольно плохим ответом. хоть. Kamil Maciorowski 6 лет назад 0
Я планирую это сделать, но сейчас я собираюсь поспать около шести часов перед работой. Написание правильного объяснения каждой части, что она делает и почему это было сделано, займет немного больше времени, чем я могу дать прямо сейчас. Я просто пытался понять, доберусь ли я до решения этой проблемы сегодня вечером или мне понадобится больше информации по проблеме. Wade S 6 лет назад 0
Когда вы все сделаете правильно, пожалуйста, оставьте мне комментарий под вопросом, начиная с @KamilMaciorowski. Тогда, если ваше объяснение имеет смысл, я с радостью приветствую ответ. Kamil Maciorowski 6 лет назад 0

0 ответов на вопрос

Похожие вопросы