LINUX.ORG.RU

sed: посимвольно обнулить значение параметра


0

2

Думаю вопрос простой для знатоков и не особо знатоков sed'а
Есть файл со строками вида
Param = Value

Value в моем случае некое хекс число (т.е. цифры + латинские буквы) неизвестной длины

Надо из
Param = 498ab28736

Получить
Param = 0000000000

т.е. заменить все символы Value на нули

Я застрял на этом этапе:
sed -i '/Param/s/ тут какой то трюк с подменой символов /g' file

★★★★★

Тебе нужно заменить все хекс-символы ([:xdigit:]) на 0:

s/[[:xdigit:]]/0/g

anonymous ()
Ответ на: комментарий от anonymous

Спасибо, я уже вижу свет в конце туннеля, но как и ожидалось
Param = 456ad678
заменилось на
P0r0m = 00000000

как заменять только после знака равно(=) ? (хотя может есть и более элегантный способ)

zolden ★★★★★ ()

> sed

домашнее задание?

если нет, то perl -i 's/^([^=]+=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' some.cfg

arsi ★★★★★ ()

awk - не?

rain@acnote:~$ echo Param = 456ad678 | awk '{print $1, $2, gensub(/[[:xdigit:]]/, «0», «G», $3)}'
Param = 00000000

YAR ★★★★★ ()
Ответ на: комментарий от zolden

А дальше пишешь ещё один паттерн, который заменяет P0r0m на Param ;)

Более «правильные» решение займут больше места.

anonymous ()
Ответ на: комментарий от arsi

на удивления на железке нашёлся даже перл, хотя железка очень специфичная. но не взлетело:

# perl -i 's/^([^=]+=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini
Can't open perl script «s/^([^=]+=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie»: No such file or directory

zolden ★★★★★ ()
Ответ на: комментарий от YAR

Думал про awk, но он не заточен под inline редактирование = лишний геморрой, так как мне не выводить строку надо а именно сохранять файл.

zolden ★★★★★ ()
Ответ на: комментарий от zolden

/me посыпает голову пеплом....

perl -i -pe 's/^([^=]+=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini

а так? :)

arsi ★★★★★ ()
Ответ на: комментарий от zolden

ну так в чем проблема?

awk 'some magic' infile > outfile && mv outfile infile

sed -i делает то же самое со входным файлом, только незаметно )

YAR ★★★★★ ()
Ответ на: комментарий от anonymous

а ты хитрый :)
Да, судя по интернетам дальнейшей углубление приводит к очень пугающим листингам. Попробую пока такой костыль, чем чёрт не шутит...

zolden ★★★★★ ()
Ответ на: комментарий от YAR

мм...в таком виде неплохой вариант, согласен

zolden ★★★★★ ()
Ответ на: комментарий от arsi

Так сработало, спасибо. Но заменились значения всех параметров. Как менять точечно только для Param1?

zolden ★★★★★ ()
Ответ на: комментарий от zolden

> Как менять точечно только для Param1?

perl -i -pe 's/^(Param1\s*=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini

для Param(число):

perl -i -pe 's/^(Param\d+\s*=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini

для Param(возможно_число):

perl -i -pe 's/^(Param\d*\s*=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini

для Foo, Bar, Baz:

perl -i -pe 's/^((?:Foo|Bar|Baz)\s*=\s*)([\da-f]+)(\s*)$/$1.(0 x length$2).$3/ie' config.ini

итп.

arsi ★★★★★ ()
Ответ на: комментарий от YAR

м, чуть не так, еще печатать неизмененные строки

YAR ★★★★★ ()
Ответ на: комментарий от YAR

ога, и как же печатать неизменённые строки если будет фильтр
awk -F= '/Param1/{blablabla print}' file
?

zolden ★★★★★ ()

sed 's/\(.*\)=/\1= 00000000000/'

anonymous ()
Ответ на: комментарий от arsi

Спасибо, так заработало.
По итогам смс-голосования ваш вариант призан годным и наименее геморройным, но наиболее страшно выглядящим.
Как наивны были мои надажды на однострочник на sed'e :)

zolden ★★★★★ ()
Ответ на: комментарий от zolden

rain@acnote:/tmp$ awk '{if ($1==«Param2») print $1, $2, gensub(/[[:xdigit:]]/, «0», «G», $3) ; else print}' file
Param1 = 123ab456
Param2 = 000000000

YAR ★★★★★ ()
Ответ на: комментарий от anonymous

Я чувствую вы были близки к идеалу, но вариант
sed '/Param1/s/\(.*\)=/\1= 00000000000/g' config.ini

из
Param1 = abcde123
сделал
Param1 = 00000000000 abcde123

zolden ★★★★★ ()
Ответ на: комментарий от zolden

Не, ну раз так можно, то

rain@acnote:/tmp$ cat file | sed -r '/^Param2/s/(.*) = .*/\1 = 00000000/g'
Param1 = 123ab456
Param2 = 00000000

YAR ★★★★★ ()
Ответ на: комментарий от YAR

Или даже без ссылок:

$ sed '/^Param2/s/= .*/= 00000000/g' file
Param1 = 123ab456
Param2 = 00000000

YAR ★★★★★ ()
Ответ на: комментарий от YAR

Мм..опять штанга. Вообще ничего не меняется. В скрипте фигурирует Param2, а Param1 вообще никак не задействована. Так и задумано?

zolden ★★★★★ ()
Ответ на: комментарий от zolden

> Так и задумано?

Да.

rain@acnote:/tmp$ sed '/^Param1/s/= .*/= 00000000/g' file
Param1 = 00000000
Param2 = 234bc4567

YAR ★★★★★ ()
Ответ на: комментарий от zolden

а, понял в чём подвох.
Из-за выравнивания, строки могут содержать разное количество пробелов, т.е. следующие варианты корректны:
Param1 = Value
Param1=Value
Param1 = Value

Я согласен на фиксированную длину Value :) !

zolden ★★★★★ ()
Ответ на: комментарий от zolden

блин, съелось форматирование. В общем возможно любое количество пробелов перед и после знака равно

zolden ★★★★★ ()
Ответ на: комментарий от YAR

rain@acnote:/tmp$ sed -r '/^Param1 *=/s/=( *).*/=\100000000/g' file
Param1=00000000
Param2 = 234bc4567
Param1 = 00000000
Param1= 00000000

YAR ★★★★★ ()

Всем (а особенно anonymous, YAR и arsi )огромное спасибо за участие и советы, полистаю книжку по перлу на досуге, а пока остановился на варианте с седом с фиксированным количеством нулей - к чёрту универсальность :)

zolden ★★★★★ ()
Ответ на: комментарий от zolden

awk с разделителем «=» был бы самым универсальным, простым и понятным вариантом :)

YAR ★★★★★ ()
Ответ на: комментарий от zolden

> Я согласен на фиксированную длину Value :) !

perl -i -pe 's/^(Param1\s*=\s*)[\da-f]+(\s*)$/${1}00000000$2/i' config.ini

или даже:

perl -i -pe 's/^(Param1\s*=\s*)[\da-f]+/${1}00000000/i' config.ini

или вообще:

sed -i 's/^\(Param1 *= *\)[0-9a-f]\+$/\100000000/i' config.ini
arsi ★★★★★ ()

С учетом длины заменяемой строки:

$ echo -e "Param1 = ab543532\nParam2 = abcdef536039"

Param1 = ab543532
Param2 = abcdef536039

$ echo -e "Param1 = ab543532\nParam2 = abcdef536039" | awk -F'=' '$1~/Param1/ {gsub("[0-9a-f]", "0", $2); $0=$1"="$2}; {print $0}'

Param1 = 00000000
Param2 = abcdef536039

sdio ★★★★★ ()

>Думаю вопрос простой для знатоков и не особо знатоков sed'а

Для «незнатоков» есть:

1) man sed

2) раздел Job

Led ★★★☆☆ ()
Ответ на: комментарий от Led

Тебя давно пора забанить. Ты никогда не пишешь по делу, только постишь высокомерные высеры, в то время как сам не знаешь сколько будет 2*2. Иди чеши свое прыщавое ЧСВ на винфак или вконтактик.

anonymous ()
Ответ на: комментарий от Led

Пятизвездочный олень. Давно заметил, что парень явный неадекват. Как таких ублюдков ЛОР носит?

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.