LINUX.ORG.RU

Ответ на: комментарий от anarquista

почему-то оно съедает табуляцию и символ, идущие после yourtext

есть где-нибудь подробный учебник регэкспов sed, желательно на русском? я уже задолбался ковыряться в примерах

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

Тогда уж сразу читай Джеффри Фридла «Регулярные выражения» от O'Reilly - в русском переводе, кажется «Питер» выпускал. Нагуглить несложно.

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

вариант anarquista работает, но съедаются табуляция и символ после неё

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

Только что специально на файле проверил:

$ cat sed_test.txt 
a = 123
b = 456
c = 789
zxc

[ 21:33:01 ]$ cat sed_test.txt | sed 's/=[^ \t]* /= yourtext /'
a = yourtext 123
b = yourtext 456
c = yourtext 789
zxc

[ 21:33:26 ]$ 

Ты что-то делаешь не так. Может, покажешь свой вариант?

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

есть где-нибудь подробный учебник регэкспов sed, желательно на русском?

у тебя в системе. info sed называется. Перевод у меня есть.

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

Внимательно посмотрел - возник вопрос: а зачем отрицание в квадратных скобках?

Дополнил тест-файл строками с табуляциями:

[ 21:53:06 ]$ cat sed_test.txt 
a = 123
b = 456
c = 789
zxc
f =	000
q =	test

[ 21:55:23 ]$ cat sed_test.txt | sed 's/=[ \t]*/= yourtext /'
a = yourtext 123
b = yourtext 456
c = yourtext 789
zxc
f = yourtext 000
q = yourtext test

[ 21:55:26 ]$ 

Всё работает.

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

я копипастой в терминал вставляю, ошибок быть не может

однако не работает, файл вообще не изменяется

строка:

/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=native/14.04.2012-22.25           0 0
fragment ()
Ответ на: комментарий от fragment

в смысле, вставляю копипастой, дополняя нужными опциями (-i, имя файла)

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

Тьфу, а я уже в другую сторону поехал... :) Так тебе надо от знака равенства до первого встреченного пробела текст заменить? Тот, который «native/14.04.2012-22.25», так что ли?

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

Тогда доктор Батти всё правильно сказал. Я файл подкорректировал и твою строку туда вписал:

[ 22:09:17 ]$ cat sed_test.txt 
a=123 
b=456	
c=789 
zxc	
f=000 
q=test 
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=native/14.04.2012-22.25           0 0

[ 22:09:20 ]$ cat sed_test.txt | sed 's/=\S*\s/=yourtext /'
a=yourtext 
b=yourtext 
c=yourtext 
zxc	
f=yourtext 
q=yourtext 
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=yourtext           0 0

[ 22:09:23 ]$ 

Так правильно?

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

Тогда ещё одна «коррекция», для наглядности:

[ 22:18:55 ]$ cat sed_test.txt 
a=123 321
b=456	654
c=789 987
zxc	
f=000 777
q=test quest
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=native/14.04.2012-22.25           0 0

[ 22:19:00 ]$ cat sed_test.txt | sed 's/=\S*\s/=yourtext /'
a=yourtext 321
b=yourtext 654
c=yourtext 987
zxc	
f=yourtext 777
q=yourtext quest
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=yourtext           0 0

[ 22:19:03 ]$ 

Ну так-то работает? :)

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

Не совсем. :)

Это же у тебя fstab, как я понимаю?

А там желательно пробелы и табуляции сохранять, как было до замены. (Или я ошибаюсь? не помню точно). Но на всякий случай - вариант с сохранением пробелов и табуляций:

[ 22:24:03 ]$ cat sed_test.txt 
a=123 321
b=456	654
c=789 987
zxc	
f=000 777
q=test quest
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=native/14.04.2012-22.25           0 0

[ 22:24:19 ]$ cat sed_test.txt | sed 's/=\S*\(\s*\)/=yourtext\1/'
a=yourtext 321
b=yourtext	654
c=yourtext 987
zxc	
f=yourtext 777
q=yourtext quest
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=yourtext           0 0

[ 22:24:23 ]$ 

То есть после замены все пробелы и табуляции будут восстановлены в состояние «до замены».

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

Да, так тоже всё работает:

так лучше. Это тоже символьный класс [[:space:]].

`

' `[^LIST]' Matches any single character in LIST: for example, `[aeiou]' matches all vowels. A list may include sequences like `CHAR1-CHAR2', which matches any character between (inclusive) CHAR1 and CHAR2.

A leading `^' reverses the meaning of LIST, so that it matches any single character _not_ in LIST. To include `]' in the list, make it the first character (after the `^' if needed), to include `-' in the list, make it the first or last; to include `^' put it after the first character.

The characters `$', `*', `.', `[', and `\' are normally not special within LIST. For example, `[\*]' matches either `\' or `*', because the `\' is not special here. However, strings like `[.ch.]', `[=a=]', and `[:space:]' are special within LIST and represent collating symbols, equivalence classes, and character classes, respectively, and `[' is therefore special within LIST when it is followed by `.', `=', or `:'. Also, when not in `POSIXLY_CORRECT' mode, special escapes like `\n' and `\t' are recognized within LIST. *Note Escapes::.

\s просто краткая запись. Не радует, что \d не работает (а в перловке работает).

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

А там желательно пробелы и табуляции сохранять, как было до замены. (Или я ошибаюсь? не помню точно).

можно и не сохранять, на работу это НЕ повлияет. Но лучше сохранить - читать удобнее.

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

sed 's/=\S*\(\s\)/subvol=yourtext\1/'

//fixed. Вообще-то там может быть и не одно «=», а нам надо менять только subvol. Кроме того, хотя-бы один пробел должен быть. А с вашим скриптом его может и НЕ быть - \s* совпадает даже с пустой строкой, и с «дыркой» между символами, которой IRL нету.

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

Ну не помню я точно. :)

Помню только, что некоторые конфиги трепетно к пробелам и табам относятся. И что лучше в них сохранять «всё, как было до».

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

Помню только, что некоторые конфиги трепетно к пробелам и табам относятся. И что лучше в них сохранять «всё, как было до».

помнить такую ерунду - голову сломаешь :-)

fields on each line are separated by tabs or spaces.

PS: кстати, вы неправильно делаете, ибо там же (man fstab)

fstab is only read by programs, and not written; it is the duty of the system administrator to properly create and maintain this file.

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

Согласен с замечаниями.

Но можно и плюсик поставить, экранированный. Тогда, как «один и более пробельных символов» считаться будет.

sed 's/=\S*\(\s\+\)/subvol=yourtext\1/'

Проверил, вроде бы работает. Но м.б. я ещё что-то не учёл...

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

Проверил, вроде бы работает. Но м.б. я ещё что-то не учёл...

вообще говоря, этот параметр может быть и не последним. Например

defaults,noatime,subvol=native/14.04.2012-22.25,discard,ssd

т.ч. надо sed -r 's/(subvol=)[^, \t]+(,| |\t)/\1youtext\2/'

как-то так (не проверил).

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

Вот в том-то и дело. Тем более я не админ. :)

да я тоже... быдлокодер, а не сисадмин. И пишу ессно не на sed :-)

drBatty ★★ ()

Новая проблема: как в строку

's/subvol=\S*\(\s*\)/subvol=yourtext\1/'

вместо yourtext подставить текст, находящийся в переменной $PATH? в sed вообще можно подставлять переменные?

это в скрипте, если что

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

fragment

вместо yourtext подставить текст, находящийся в переменной $PATH? в sed вообще можно подставлять переменные?

можно, пока это строчка bash'а... Только очень осторожно. В принципе что-то вроде $PATH можно подставить так:

's~subvol=\S*\(\s*\)~subvol='"$PATH"'\1~'
тут на самом деле три строчки: 'первая' «вторая» 'третья', они записаны слитно, потому bash воспринимает их как одну лексему. Причём $PATH раскрывается как переменная (двойные кавычки), а остальное не раскрывается.

Ну а в силу того, что в $PATH полно слешей, я в качестве разделителя заюзал ~, их вроде быть не должно.

Хотя вообще, что sed, что bash для написания безопасного ПО подходит слабо. Вот только альтернативы ещё не придумали... Ну не C же, и уж прости мну Патрег не php...

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

fragment

я так не пишу

ну тут фишка в том, что нет никакой разницы, сколько пробельных символов захватит (\s*), хоть ноль, хоть Over9000. Скрипт всё равно будет правильно работать. ВСЕ непробельные символы будут захвачены (\S*) (из за жадности), и потому ставить туда ещё и (\s*) попросту не имеет смысла. Ну если нравится...

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

Вообще-то, надо еще перед подстановкой заэкранировать в переменной символы,
которые sed может посчитать за специальные, а это зависит и от режима базовые/расширенные regexp, и от того, куда именно в sed-скрипте подставлять - поле адреса/поле поиска в s/поле замены в s..., и учитывать что в regexp правила тоже разные в зависимости от позиции...
В общем, тот еще гемморой в общем случае, если не хочешь, чтобы sed «внезапно» слетал по неверному синтаксису или, хуже того, порол чушь.
В именах файлов могут встречаться любые символы, кроме 0x0 и «/», так что в общем случае в «${PATH}» может оказаться что угодно, включая «~» и \n.

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

's~subvol=\S*\(\s*\)~subvol='«$PATH»'\1~'

не работает

я вот думаю - может, легче будет тупо удалять первую строку в fstab и вместо неё всовывать нужную? только я не пойму, как добавить первую строку в файл

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

fragment

слэш там всего один

$ echo "$PATH" | sed 's![^/]!!g' | wc -c
34

fragment

и я о слэшах как-то не подумал

ничего - на эти грабли все постоянно наступают, в т.ч. и я :)

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

$PATH - это не переменная окружения, а локальная переменная в скрипте

да, я в курсе, что такие имена давать некрасиво -)

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

fragment

или просто использовать awk, у него нет такой аллергии на слэши

кто вам такую глупость сказал?? http://www.gnu.org/software/gawk/manual/html_node/Regexp.html#Regexp Кстати, регулярок вообще нет. Ни в gawk ни в sed. Они в glibc.

fragment

не работает

$ echo '/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=native/14.04.2012-22.25           0 0' | sed 's~subvol=\S*\(\s*\)~subvol='"$PATH"'\1~'
/dev/sda4                       /               btrfs           defaults,noatime,discard,ssd,subvol=/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/java/bin:/usr/lib/java/jre/bin:/usr/lib/java/bin:/usr/lib/kde4/libexec:/usr/lib/qt/bin:/usr/share/texmf/bin:.           0 0

что не так?

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

fragment

$PATH - это не переменная окружения, а локальная переменная в скрипте

ССЗБ

fragment

да, я в курсе, что такие имена давать некрасиво -)

в bash & sed и так Over9000 граблей, вам мало?

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

не знаю, пишет:

./volselect: line 11: sed: команда не найдена

11-ая строка - это как раз это:

sed -i 's~subvol=\S*\(\s*\)~subvol='"$PATH"'\1~' fstab

в $PATH у меня вот это:

native/27.04.2012-22.07.09

может, дефис мешает?

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

ABW

Вообще-то, надо еще перед подстановкой

а вам, господин теоретик, я предлагаю реализовать данную процедуру. Уверен, что после того, как вы её реализуете, со всех податчётных вам носителей исчезнут все такие кривые файлы, вы их будете жечь напалмом shred'ом, с ключом -n666. По себе знаю.

ABW

так что в общем случае в «${

...и в общем случае, _у вас_ таких файлов точно не будут. У меня-то их нет :-)

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