Замена строки
Модераторы: /dev/random, Модераторы разделов
-
- Сообщения: 107
- ОС: Linux
Замена строки
Добрый день.
Нужно в файле найти строку по определенному критерию и дописать выражение в конец строки. Делаю следующим образом:
CHANGE_LINE=`cat file | grep критерий_1 | grep критерий_2`;
NEW_LINE=`echo "$OLD_LINE $1"`;
echo $NEW_LINE;
echo $CHANGE_LINE;
TEMP="perl -pi -e 's/(^|[\s.=\/:])${CHANGE_LINE}([\s.>:])/\${1}${NEW_LINE}\${2}/' file"
echo $TEMP;
eval $TEMP;
Строка имеет вид:
критерий_1 критерий_2 bbbbbbbb cccccccc
Скрипт выполняется но строка не изменяется, буду благодарен за любую помощь.
Нужно в файле найти строку по определенному критерию и дописать выражение в конец строки. Делаю следующим образом:
CHANGE_LINE=`cat file | grep критерий_1 | grep критерий_2`;
NEW_LINE=`echo "$OLD_LINE $1"`;
echo $NEW_LINE;
echo $CHANGE_LINE;
TEMP="perl -pi -e 's/(^|[\s.=\/:])${CHANGE_LINE}([\s.>:])/\${1}${NEW_LINE}\${2}/' file"
echo $TEMP;
eval $TEMP;
Строка имеет вид:
критерий_1 критерий_2 bbbbbbbb cccccccc
Скрипт выполняется но строка не изменяется, буду благодарен за любую помощь.
-
- Сообщения: 1205
- ОС: Debian Wheezy (amd64)
Re: Замена строки
Примерно так. Развивайте по аналогии
Код: Выделить всё
cat yourfile | sed -r 's/.*критерий_1.*/\0 Exists1/'
упс минутку..... написал не проверив..... не совсем то наверное... ейчас проверю
То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
-
- Сообщения: 1205
- ОС: Debian Wheezy (amd64)
Re: Замена строки
Код: Выделить всё
cat t.txt | sed 's/.*критерий_1.*/\0/;s/.*критерий_2.*/\0 E/'
Добавляется Е в строку где есть оба критерия в любом порядке
То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
Спасибо сказали:
-
- Сообщения: 107
- ОС: Linux
Re: Замена строки
Voral писал(а): ↑19.02.2010 11:33Код: Выделить всё
cat t.txt | sed 's/.*критерий_1.*/\0/;s/.*критерий_2.*/\0 E/'
Добавляется Е в строку где есть оба критерия в любом порядке
Большое спасибо, все работает.
Тему можно закрывать.
-
- Сообщения: 107
- ОС: Linux
Re: Замена строки
Есть трабл в скрипте. Если критерий_2 встречается в тексте более одного раза (хотя вместе с первым один раз) то дописывается после каждой строки где есть критерий 2.
-
- Сообщения: 107
- ОС: Linux
Re: Замена строки
Прописал следующим образом, теперь вроде обрабатывает так как нужно:
sed 's/.*критерий_1.*критерий_2.*/\0 E/'
-
- Сообщения: 586
- Статус: -
Re: Замена строки
Критерий у вас какая-то специальная метка или он может встречаться в тексте? Если метка, то ваш скрипт можно сломать :-) Т.е если критерий специальная метка, и вы хотите выборку только по этим меткам (т.е чтобы сам текст после меток не сканировался на совпадения), то такой случай
Код: Выделить всё
|------метки------||---------текст-------|
критерий_1 ..критерий_2
приведет к неправильным результатам, тк критерия_2 нету в зоне меток (но он есть в зоне текста, а ваш скрипт сканирует и то, и то, не различая их).
Впрочем, если вам критерии нужно искать везде по тексту, то все нормально :-)
-
- Сообщения: 1205
- ОС: Debian Wheezy (amd64)
Re: Замена строки
Решение в лоб. Проверить нет времени. Попробуйте. Если, что вечером разберемся
Код: Выделить всё
cat t.txt | sed -r 's/.*((критерий_1.*критерий_2)|(критерий_2.*критерий_1)).*/\0 E/'
Только в этом случае порядок следования имеет значение
То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
-
- Сообщения: 107
- ОС: Linux
Re: Замена строки
Как раз порядок имеет значение.
sgfault -- Критерии нужно искать везде по тексту.
Всем спасибо.
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Замена строки
Ух, наворотили...
Дословный перевод на sed с русского:
Код: Выделить всё
/критерий1.*критерий2/ s/$/новый текст/
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 586
- Статус: -
Re: Замена строки
Voral писал(а): ↑19.02.2010 13:47Решение в лоб. Проверить нет времени. Попробуйте. Если, что вечером разберемся
Код: Выделить всё
cat t.txt | sed -r 's/.*((критерий_1.*критерий_2)|(критерий_2.*критерий_1)).*/\0 E/'
Voral, Кстати, про '\0': насколько я понимаю, это back reference (который работает, как '&'), но в `info sed` написано, что номер может быть 1-9. А про '\0' нигде ничего. Так откуда же вы его взяли ? :-)
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Замена строки
t.t
требуется ещё и произвольная последовательность критериев.
sed '/критерий1.*критерий2/s/$/нашлось/;ta;/критерий2.*критерий1/s/$/нашлось/;:a'
Voral
ваше предложение будет работать очень медленно.
требуется ещё и произвольная последовательность критериев.
sed '/критерий1.*критерий2/s/$/нашлось/;ta;/критерий2.*критерий1/s/$/нашлось/;:a'
Voral
ваше предложение будет работать очень медленно.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
в этом случае используйте команды переходов:
Код: Выделить всё
s/критерий 1/&/
# если первого критерия нет, то следующая команда завершит скрипт
T
s/критерий 2/&/

Абсолютно верно!
как-это - не написано?!
написано. 0-9:
0 - первое подвыражение
1 - второе
2 - третье
и т.д.
какой-то у вас info неправильный.
тут нужно использовать GNU-расширение T - переход если НЕ нашлось. и метки не надо, она и так есть, по умолчанию.
/(X.*Y)|(Y.*X)/
это? сложно сказать: в большинстве систем чтение файла будет ещё медленнее. Заметить разницу можно будет только если файл лежит в памяти (например файл небольшой, 0...100Мб, и читается не в первый раз, что обычно и случается).
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Замена строки
да, метки не надо. но команда должна быть t, а не T.
ничего сложного. четыре звёздочки будут однозначно дольше отрабатывать, нежели две. и не в _два_ раз дольше.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Замена строки
Не заметил насчёт произвольная. По твоему варианту: ментка не нужна -- t без метки переходит в конец скрипта.
sed '/критерий1.*критерий2/ s/$/нашлось/; t; /критерий2.*критерий1/ s/$/нашлось/'
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 586
- Статус: -
Re: Замена строки
да он и не у меня вовсе
_http://www.gnu.org/software/sed/manual/sed.html
Я не нашел там ничего про \0.
первое? Ведь это весь pattern space, первое выделенное \(\) - это \1. Разве нет?
PS.
Если открывать ссылку неохота:
Код: Выделить всё
The replacement can contain \n (n being a number from 1 to 9, inclusive) references
PS2. Большой разницы, конечно, нет, но, тк я этого не нашел в официальном мануале, у меня возникают сомнения насколько работа этой ссылки.. мм.. стабильна (т.е что не получится так, что в новой или какой-то старой версии это не будет работать).
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
угу.
Код: Выделить всё
sed '
/критерий1.*критерий2/{
s/$/нашлось/
}
ta;
/критерий2.*критерий1/{
s/$/нашлось/
}
:a
'
это даже работает... вот только команда t выполняется В ТОМ, И ТОЛЬКО В ТОМ случае, если сработало адресное выражение, т.к. якорное выражение ($) присутствует ВСЕГДА, потому и команда t работает ВСЕГДА, внутри этого блока операций. Логичнее переписать так:
Код: Выделить всё
/критерий1.*критерий2/{
s/.*/нашлось/
}
/критерий2.*критерий1/{
s/.*/нашлось/
}
Что по времени выполнения совершенно эквивалентно выражению
Код: Выделить всё
/(критерий1.*критерий2)|(критерий2.*критерий1)/s/.*/нашлось/
Это выражение ищется точно так-же как у вас, вот только записано оно короче и яснее. Впрочем вы правы, тут нужны прямые ссылки на исходные тексты, а их как раз-таки у меня сейчас под рукой и нет.
не думаю... ну это мы ещё проверим.
ну во первых - спасибо. буду знать. на самом деле, применял у себя символ \0 только по одной причине: символ & ну никак не ложится ни в HTML ни в docbook. И там и там надо писать &, что мне - лениво. Про \0 я всё-же прочитал в одном из мануалов (а не сам придумал), и это было связано с тем, что кто-то здесь спрашивал, "почему не работают в sed комбинации вроде \033, в отличие от bash'а". Оказалось, что в отличие от нашей оболочки, в sed восьмеричное представление записывается как \o33, а не с лидирующем нулём, я тоже обещаю поглядеть документацию, и/или исходные тексты разных версий sed, что-бы окончательно разобраться с этим вопросом (кроме того, мне придётся перечитать POSIX стандарт на эти **** регулярные выражения, может там про это тоже написано).
-
- Сообщения: 586
- Статус: -
Re: Замена строки
drBatty писал(а): ↑24.02.2010 22:23
ну во первых - спасибо. буду знать. на самом деле, применял у себя символ \0 только по одной причине: символ & ну никак не ложится ни в HTML ни в docbook. И там и там надо писать &, что мне - лениво. Про \0 я всё-же прочитал в одном из мануалов (а не сам придумал), и это было связано с тем, что кто-то здесь спрашивал, "почему не работают в sed комбинации вроде \033, в отличие от bash'а". Оказалось, что в отличие от нашей оболочки, в sed восьмеричное представление записывается как \o33, а не с лидирующем нулём, я тоже обещаю поглядеть документацию, и/или исходные тексты разных версий sed, что-бы окончательно разобраться с этим вопросом (кроме того, мне придётся перечитать POSIX стандарт на эти **** регулярные выражения, может там про это тоже написано).
Если стандарт POSIX - это _http://www.opengroup.org/onlinepubs/009695399/utilities/sed.html , то все, что я там нашел это
Код: Выделить всё
The replacement string shall be scanned from beginning to end. An ampersand ( '&' ) appearing in the replacement shall be replaced by the string matching the BRE. The special meaning of '&' in this context can be suppressed by preceding it by a backslash. The characters "\n", where n is a digit, shall be replaced by the text matched by the corresponding backreference expression.
Может вам удастся найти больше :-)
-
- Администратор
- Сообщения: 5403
- ОС: Gentoo
Re: Замена строки
Согласно POSIX, запись \0 может интерпретироваться по-разному, в зависимости от реализации. Но на практике я ещё ни разу в жизни не встречал реализации (и не только sed, а regex вообще), где это не было бы синонимом для &.
-
- Сообщения: 586
- Статус: -
Re: Замена строки
/dev/random писал(а): ↑24.02.2010 23:06Согласно POSIX, запись \0 может интерпретироваться по-разному, в зависимости от реализации. Но на практике я ещё ни разу в жизни не встречал реализации (и не только sed, а regex вообще), где это не было бы синонимом для &.
Аригато, я этого не знал :-)
PS. На следующий пост:
хм.. даже не знаю. Привычка, наверное :-)
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
нет. это немного не то. нужно найти примерно то-же, только про регулярные выражения. я что-то тоже там ничего путного не нашёл...
ЗЫЖ а зачем делать ссылки некликабельными?
-
- Сообщения: 229
- ОС: Windows Vista
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
что-то не так?
там может быть find ... | sort -g | ...ещё что-то... | sed
может там это было, а может и нет. а если мне надо cat -n ? ставить 3 sed?
-
- Сообщения: 586
- Статус: -
Re: Замена строки
Хоть cat и лишний, но ведь никакой принципиальной разницы нет - в конце концов, имеет значение лишь решение задачи (сам скрипт, алгоритм), а не `cat | sed` или `sed file`. Да и, как заметил drBatty, cat может стоять просто для сокращения условия задачи, а в реальном примере там могут быть совершенно другие команды. Хотя с точки зрения, что лучше всегда писать правильно (правильно по отношению к известному условию задачи), вы, конечно, правы.
-
- Сообщения: 586
- Статус: -
Re: Замена строки
/dev/random писал(а): ↑24.02.2010 23:06Согласно POSIX, запись \0 может интерпретироваться по-разному, в зависимости от реализации. Но на практике я ещё ни разу в жизни не встречал реализации (и не только sed, а regex вообще), где это не было бы синонимом для &.
И все же, все же:
IEEE Std 1003.1, 2004 Edition (http://www.opengroup.org/onlinepubs/000095399/toc.htm) (ведь это POSIX, да?)
Код: Выделить всё
9.3.6 BREs Matching Multiple Characters
<...>
3. The back-reference expression '\n' shall match the same (possibly empty) string of characters as was matched by a subexpression enclosed between "\(" and "\)" preceding the '\n'. The character 'n' shall be a digit from 1 through 9, specifying the nth subexpression (the one that begins with the nth "\(" from the beginning of the pattern and ends with the corresponding paired "\)" ).
Насколько я понимаю, это и есть нужный раздел стандарта про регулярные выражения, вот только про \0 там по-прежнему ничего нет :-)
/dev/random, не то, чтобы я вам не верю, но ведь в стандарте про это все же ничего нет. Или я просто не там искал? :-)
-
- Администратор
- Сообщения: 5403
- ОС: Gentoo
Re: Замена строки
Код: Выделить всё
The replacement string shall be scanned from beginning to end. An ampersand ( '&' ) appearing in the replacement shall be replaced by the string matching the BRE. The special meaning of '&' in this context can be suppressed by preceding it by a backslash. The characters "\n", where n is a digit, shall be replaced by the text matched by the corresponding backreference expression. The special meaning of "\n" where n is a digit in this context, can be suppressed by preceding it by a backslash. For each other backslash ( '\' ) encountered, the following character shall lose its special meaning (if any). The meaning of a '\' immediately followed by any character other than '&', '\', a digit, or the delimiter character used for this command, is unspecified.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
разница есть - cat просто сольёт все файлы в один, а вот sed может обработать их отдельно (с ключами -s и -i). и ещё, то, что между sed '' file принципиально нельзя ничего поставить, мне кажется - принципиально. (хотя можно, xargs sed '' например, но это уже принципиально иной подход)
в стандарте я тоже не нашёл, однако где-то в документации вроде было пару слов... в bash конструкция \0ooo означает совсем другое
-
- Сообщения: 1205
- ОС: Debian Wheezy (amd64)
Re: Замена строки
Прикольно получилось с этим \0. Даже достал букварь в котором я первый раз узнал о регулярных выражениях (справочник php). И там то же значится "больше 0 и меньше 100".... Ну и на "автомате" здесь применил..... Могу только предположить почему я так сделал php-шная функция preg_match заполняет (если указан параметр) массив найденными совпадениями. Элемент с индексом 0 это соответствие полному шаблону. Очевидно, что я просто по аналогии сделал, получилось и не разу не подводило....
Мдас........
Мдас........
То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
When life puts you in tough situations, don’t say "why me". Just say "try me © ?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Замена строки
Voral писал(а): ↑25.02.2010 12:39Могу только предположить почему я так сделал php-шная функция preg_match заполняет (если указан параметр) массив найденными совпадениями. Элемент с индексом 0 это соответствие полному шаблону. Очевидно, что я просто по аналогии сделал, получилось и не разу не подводило....
может это для исполнения хитрых RE, когда одно RE генерирует другое, для единообразия и ввели ссылку \0 (такое возможно в php, но невозможно в sed, т.к. sed с ключём s выполняет не другую sed, а другой shell. Конечно можно и извратится - в другом shell выполнить другую sed.)
-
- Сообщения: 586
- Статус: -
Re: Замена строки
/dev/random писал(а): ↑25.02.2010 12:28Код: Выделить всё
The replacement string shall be scanned from beginning to end. An ampersand ( '&' ) appearing in the replacement shall be replaced by the string matching the BRE. The special meaning of '&' in this context can be suppressed by preceding it by a backslash. The characters "\n", where n is a digit, shall be replaced by the text matched by the corresponding backreference expression. The special meaning of "\n" where n is a digit in this context, can be suppressed by preceding it by a backslash. For each other backslash ( '\' ) encountered, the following character shall lose its special meaning (if any). The meaning of a '\' immediately followed by any character other than '&', '\', a digit, or the delimiter character used for this command, is unspecified.
это.. но тут ничего не сказано про \0 (и, кстати, этот отрывок из http://www.opengroup.org/onlinepubs/009695...lities/sed.html уже приводился выше). И даже если под тем, что не указано явно 0 < n < 10 понимать, что \0 допустимо, то в этом отрывке уж точно не сказано, что \0 должен быть синонимом &.