Прочитать файл до определённой строки (Чем?)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
30.11.2010 02:21
ZyX писал(а):
26.11.2010 01:51
Но это никак не связано с тем, что команды sed не задуманы, чтобы их читали. Без списка команд sed и расставления переносов и пробелов нет никаких шансов понять, что происходит.

у sed всего штук 30-40 команд (из которых 80% почти никогда не применяется). А сколько команд в вашем любимом языке? (да, в С их немного. за то over9000 совершенно необходимых функций, без которых даже helloworld не написать). Что до форматирования, то убрав форматирование, можно сделать нечитаемым код на любом языке. Но если это не пайтон, то работать он всё равно будет.

При уборке форматирования perl не обязательно станет нечитаемым. При уборке форматирование любой сколько-нибудь сложный скрипт на sed станет нечитаемым.
drBatty писал(а):
30.11.2010 02:21
ZyX писал(а):
26.11.2010 01:51
И хуже работает:

в смысле, "хуже"?

ZyX писал(а):
26.11.2010 01:51
И хуже работает: посмотрите на вариант sash-kan, в котором это дело дополнительно распихивается по файлам.
Предложения надо читать до конца. Ваш скрипт ничего никуда не распихивает, поэтому он хуже работает.

drBatty писал(а):
30.11.2010 02:21
ZyX писал(а):
26.11.2010 02:18
Недостатков даже больше:

а мой скрипт тут причём? там можно всякие <|>

Не понял. Это вы про shell pipe?
Понял. Ваш скрипт тут не при чём, просто я показываю преимущества использования «серьёзного» языка программирования против кучи узко специализированных утилит. Вообщем-то, такой спор начинается каждый раз, когда тут пишут скрипт на sed/awk/tcl(expect), за исключением тех случаев, когда тема была закрыта до того, как я её увидел («закрыта» в разговорном смысле, а не закрыта модератором).

drBatty писал(а):
30.11.2010 02:21

Код: Выделить всё

BEGIN{%f=qw(Кукушка coocoo Чайник teapot)}/^\s*!\s*(.*)/and open F,'>',(($f{$1})?($f{$1}):($1)).".rc"and next;print F $_ if*F;

Код: Выделить всё

sed -n '/^!/{n;:l;/\n$/{s///p;q};${p;q};N;bl}'

мой гольф лучше вашего ;)

Да ну? Ваш гольф не распихивает ничего по файлам, поэтому сравнение некорректно. Согласен, что написать что-то с тем же функционалом, но на perl и короче у меня не получится (лучший результат: /^!/?($,=1,$_=""):$,?/^$/&&last:undef$_: на два символа длиннее), но вы уж лучше добавьте распихивание по файлам и тогда посмотрим.

Кстати, откуда вы взяли условие пустой строки? В исходном сообщении требовались линии, начинающиеся с пробела. У меня это выразиться в замене трёх символов: /^$/&&last/^ /||last.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

watashiwa_darede... писал(а):
30.11.2010 17:18
Это я к тому, что малое количество команд слабо коррелирует с читаемостью программы.

никто не спорит, это был ответ на:
Без списка команд sed и расставления переносов и пробелов нет никаких шансов понять, что происходит.

ZyX писал(а):
30.11.2010 21:14
При уборке форматирования perl не обязательно станет нечитаемым. При уборке форматирование любой сколько-нибудь сложный скрипт на sed станет нечитаемым.

вопрос привычки. это только ДЛЯ ВАС так. А вот для меня - наоборот.
ZyX писал(а):
30.11.2010 21:14
Предложения надо читать до конца. Ваш скрипт ничего никуда не распихивает, поэтому он хуже работает.

а что и куда надо распихивать? в условии задачи это было?
ZyX писал(а):
30.11.2010 21:14
Понял. Ваш скрипт тут не при чём, просто я показываю преимущества использования «серьёзного» языка программирования против кучи узко специализированных утилит.

ну а вы зря считаете sed - "несерьёзным" ЯП. Она ничем не хуже вашей перловки ;)
(зависит от задачи, что хуже, а что лучше)
ZyX писал(а):
30.11.2010 21:14
Да ну? Ваш гольф не распихивает ничего по файлам, поэтому сравнение некорректно. Согласен, что написать что-то с тем же функционалом, но на perl и короче у меня не получится (лучший результат: /^!/?($,=1,$_=""):$,?/^$/&&last:undef$_: на два символа длиннее), но вы уж лучше добавьте распихивание по файлам и тогда посмотрим.

я так и не понял, что и куда пихать.
ZyX писал(а):
30.11.2010 21:14
Кстати, откуда вы взяли условие пустой строки? В исходном сообщении требовались линии, начинающиеся с пробела. У меня это выразиться в замене трёх символов: /^$/&&last → /^ /||last.

да? а как я понял - любые строки, а окончанием блока служит пустая строка. ничто не помешает это поменять. Дайте более чёткое условие.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
01.12.2010 04:06
ZyX писал(а):
30.11.2010 21:14
При уборке форматирования perl не обязательно станет нечитаемым. При уборке форматирование любой сколько-нибудь сложный скрипт на sed станет нечитаемым.

вопрос привычки. это только ДЛЯ ВАС так. А вот для меня - наоборот.

По-хорошему, здесь надо найти программиста, не работавшего ни с тем, ни с другим и спросить его. Только не показывайте ему мой последний вариант.
drBatty писал(а):
01.12.2010 04:06
а что и куда надо распихивать? в условии задачи это было?

gluk47 писал(а):
19.11.2010 13:53
Мне нужно добавить данные первого объекта в один файл (путь будет coocoo.rc), данные второго — в teapot.rc.

Дальше идёт про переменную, но во временные файлы распихать легче.

drBatty писал(а):
01.12.2010 04:06
ну а вы зря считаете sed - "несерьёзным" ЯП. Она ничем не хуже вашей перловки ;)
(зависит от задачи, что хуже, а что лучше)

Я считаю его «несерьёзным», потому что количество задач, для которых подходит sed гораздо меньше, чем количество задач, для которых подходит perl.

drBatty писал(а):
01.12.2010 04:06
ZyX писал(а):
30.11.2010 21:14
Да ну? Ваш гольф не распихивает ничего по файлам, поэтому сравнение некорректно. Согласен, что написать что-то с тем же функционалом, но на perl и короче у меня не получится (лучший результат: /^!/?($,=1,$_=""):$,?/^$/&&last:undef$_: на два символа длиннее), но вы уж лучше добавьте распихивание по файлам и тогда посмотрим.

я так и не понял, что и куда пихать.
ZyX писал(а):
30.11.2010 21:14
Кстати, откуда вы взяли условие пустой строки? В исходном сообщении требовались линии, начинающиеся с пробела. У меня это выразиться в замене трёх символов: /^$/&&last → /^ /||last.

да? а как я понял - любые строки, а окончанием блока служит пустая строка. ничто не помешает это поменять. Дайте более чёткое условие.

gluk47 писал(а):
19.11.2010 13:53
(три строки с пробелами впереди)

Условие пустой строки использовалось /dev/random как более лёгкое.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
01.12.2010 07:14
По-хорошему, здесь надо найти программиста, не работавшего ни с тем, ни с другим и спросить его. Только не показывайте ему мой последний вариант.

довольно легко читаемый вариант... ну после некоторой тренировки конечно. Кстати, такой однострок даже в чём-то легче понять - воспринимаешь его одним предложением, целиком. В точности также, как родной язык. Вообще, беда большинства ЯП в многословности - та-же qsort ИМХО должна занимать пару-тройку строк, а занимает 2 страницы.
ZyX писал(а):
01.12.2010 07:14
Дальше идёт про переменную, но во временные файлы распихать легче.

это не представляет особой сложности в sed, для работы с файлами имеются команды R, r, W и w.
ZyX писал(а):
01.12.2010 07:14
Я считаю его «несерьёзным», потому что количество задач, для которых подходит sed гораздо меньше, чем количество задач, для которых подходит perl.

а вот с этим я категорически не согласен: и на sed и на perl можно реализовать любой алгоритм, вопрос в том, есть-ли в этом смысл. Конечно, ядро ОС лучше не писать ни на том, ни на другом. Что до более простых задач, то тут очень сложно сказать, когда наступает момент, когда все эти скрипты пора выкидывать в топку, и применять C (или даже ещё более абстрактный C++). И этот момент очень сильно зависит от кодера. Например для меня просто нет места perl'у - простую обработку текстов я и на sed реализую, а более сложную - на C. Просто нет ниши для perl. Если задача не связанна с текстом, и тем не менее, применять С тут не рационально, то я возьму php или python, но никак не perl. Я просто не вижу задач, к которым его можно было-бы приложить.
ZyX писал(а):
01.12.2010 07:14
Условие пустой строки использовалось /dev/random как более лёгкое.

я не очень понимаю спор
/^$/ vs /^ /!
всего 1 символ теряется.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
01.12.2010 12:13
ZyX писал(а):
01.12.2010 07:14
По-хорошему, здесь надо найти программиста, не работавшего ни с тем, ни с другим и спросить его. Только не показывайте ему мой последний вариант.

довольно легко читаемый вариант... ну после некоторой тренировки конечно. Кстати, такой однострок даже в чём-то легче понять - воспринимаешь его одним предложением, целиком. В точности также, как родной язык. Вообще, беда большинства ЯП в многословности - та-же qsort ИМХО должна занимать пару-тройку строк, а занимает 2 страницы.

Собственно, поэтому perl и входит в тройку языков, которые мне больше всего нравятся.

drBatty писал(а):
01.12.2010 12:13
ZyX писал(а):
01.12.2010 07:14
Дальше идёт про переменную, но во временные файлы распихать легче.

это не представляет особой сложности в sed, для работы с файлами имеются команды R, r, W и w.

Эм, а почему тогда sash-kan использовал небезопасный вариант с s///e? Бегло просмотрев man sed, могу предложить следующее: при отуствии eval и переменных эти команды просто нельзя использовать.

drBatty писал(а):
01.12.2010 12:13
ZyX писал(а):
01.12.2010 07:14
Я считаю его «несерьёзным», потому что количество задач, для которых подходит sed гораздо меньше, чем количество задач, для которых подходит perl.

а вот с этим я категорически не согласен: и на sed и на perl можно реализовать любой алгоритм, вопрос в том, есть-ли в этом смысл.

Нет смысла = не подходит, про что я, собственно и говорил.

drBatty писал(а):
01.12.2010 12:13
Конечно, ядро ОС лучше не писать ни на том, ни на другом. Что до более простых задач, то тут очень сложно сказать, когда наступает момент, когда все эти скрипты пора выкидывать в топку, и применять C (или даже ещё более абстрактный C++).

C не нужно трогать пока не встал вопрос о производительности. И то, в этом случае часто можно использовать что-то более высокоуровневое но компилируемое вроде Ocaml. Для замены скриптов его можно использовать только если вы ничего другого не знаете. Мне никогда не приходила в голову мысль писать на нём скрипты.

drBatty писал(а):
01.12.2010 12:13
И этот момент очень сильно зависит от кодера. Например для меня просто нет места perl'у - простую обработку текстов я и на sed реализую, а более сложную - на C. Просто нет ниши для perl. Если задача не связанна с текстом, и тем не менее, применять С тут не рационально, то я возьму php или python, но никак не perl. Я просто не вижу задач, к которым его можно было-бы приложить.

Тут возразить нечего, но у меня другая последовательность выбора языка от сложности задачи: zsh/vimScript→perl/python→Haskell (только вычисления)/C. Если я достоверно знаю, что в задаче нужна сложная обработка текста, но вопрос производительности стоит не слишком остро, то я возьму perl. Если обработка текста нужна для работы в Vim’е и вопрос производительности не стоит вообще, то я возьму vimScript, если же он стоит, то это будет Python (всё что угодно, лишь бы не трогать ужасный интерфейс к Vim’у в perl).

drBatty писал(а):
01.12.2010 12:13
ZyX писал(а):
01.12.2010 07:14
Условие пустой строки использовалось /dev/random как более лёгкое.

я не очень понимаю спор
/^$/ vs /^ /!
всего 1 символ теряется.

Тут нет спора. Просто в задаче было другое условие.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
01.12.2010 19:35
Эм, а почему тогда sash-kan использовал небезопасный вариант с s///e? Бегло просмотрев man sed, могу предложить следующее: при отуствии eval и переменных эти команды просто нельзя использовать.

1) а почему это он "не безопасный"? если криво применять ЛЮБОЙ ЯП у вас будут проблемы с безопасностью. Даже если вы и не будете применять указатели в С, GOTO в бейсике, или s///e в sed.
2) можно их использовать. почему их не использовал sash-kan - спросите у него. я их довольно часто использую.

ZyX писал(а):
01.12.2010 19:35
Нет смысла = не подходит, про что я, собственно и говорил.

"нет смысла" понятие субъективное. про что я и говорил.
ZyX писал(а):
01.12.2010 19:35
C не нужно трогать пока не встал вопрос о производительности.

для ВАС. а вот МНЕ проще потрогать С.
ZyX писал(а):
01.12.2010 19:35
Мне никогда не приходила в голову мысль писать на нём скрипты.

простите, я не вижу принципиальной разницы, между скриптами, и компилируемыми ЯП. В применении. Может расскажите, ГДЕ лежит та грань, за которой скрипты применять УЖЕ нельзя? Я её не вижу.
ZyX писал(а):
01.12.2010 19:35
Тут возразить нечего, но у меня другая последовательность выбора языка от сложности задачи: zsh/vimScript→perl/python→Haskell (только вычисления)/C.

вот то-то и оно. У вас нет места для sed, а у меня - для perl'а. Вот и всё.
у меня
sh/bash→sed→C→C++
Хотя... где-то в середине цепочки, ИМХО, надо как-нить заюзать PHP. Но на практике пока не пробовал.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
02.12.2010 08:27
ZyX писал(а):
01.12.2010 19:35
Эм, а почему тогда sash-kan использовал небезопасный вариант с s///e? Бегло просмотрев man sed, могу предложить следующее: при отуствии eval и переменных эти команды просто нельзя использовать.

1) а почему это он "не безопасный"? если криво применять ЛЮБОЙ ЯП у вас будут проблемы с безопасностью. Даже если вы и не будете применять указатели в С, GOTO в бейсике, или s///e в sed.

Чем больше возможностей нарушить нормальную работу надо учитывать при написании ПО, тем менее безопасен язык. Чтобы об этом не думать, обычно пишут библиотеки вроде ORM (хотя оно, конечно, не только улучшает безопасность). Но на sed библиотек нет.

drBatty писал(а):
02.12.2010 08:27
2) можно их использовать. почему их не использовал sash-kan - спросите у него. я их довольно часто использую.

Тогда покажите, как переписать скрипт sash-kan, используя эти команды. Я не вижу такой возможности.

drBatty писал(а):
02.12.2010 08:27
ZyX писал(а):
01.12.2010 19:35
Мне никогда не приходила в голову мысль писать на нём скрипты.

простите, я не вижу принципиальной разницы, между скриптами, и компилируемыми ЯП. В применении. Может расскажите, ГДЕ лежит та грань, за которой скрипты применять УЖЕ нельзя? Я её не вижу.

Я вообще не вижу, как язык может быть компилируемым или интерпретируемым. Перечитайте фразу, в отличие от предыдущей (где я сказал, что C не надо трогать, если не …, основанная на том, что на C сложно писать и быстро, и безопасно), здесь я сказал, что мне никогда не приходила в голову мысль … Не «нельзя», а «не приходила в голову».
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
02.12.2010 19:39
Тогда покажите, как переписать скрипт sash-kan, используя эти команды. Я не вижу такой возможности.

понятное дело, что невозможно задать в sed-скрипте имя файла. Ну и что? А мы вот такой скрипт сделаем:

Код: Выделить всё

#!/bin/sed -rf

$ a\
q

/^ /!{
    s/\W*(\w+)/\1/
    h
    d
}

G
s/\s*(.*)\n(.*)/s~.*~\1~w \2/

запустив

Код: Выделить всё

./x.sed 1 >2

мы получим такой файл 2

Код: Выделить всё

s~.*~кукует~w Кукушка
s~.*~летает~w Кукушка
s~.*~птица~w Кукушка
s~.*~свистит~w Чайник
s~.*~стоит~w Чайник
s~.*~не птица~w Чайник
s~.*~test1~w test
s~.*~test2~w test
q


осталось запустить этот файл 2

Код: Выделить всё

sed -f 2 1


Как вам такой сценарий?

ЗЫЖ конечно злоумышленник может завершить команду воспользовавшись ~, И написать своё что-нить. К примеру s~.*~rm -rf /~
потому нужно проверять строки на наличие ~ и (если используется UTF-8) на наличие НЕСИМВОЛОВ. Но это уже мелочи :-)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
03.12.2010 21:48
<...>
Как вам такой сценарий?

ЗЫЖ конечно злоумышленник может завершить команду воспользовавшись ~, И написать своё что-нить. К примеру s~.*~rm -rf /~
потому нужно проверять строки на наличие ~ и (если используется UTF-8) на наличие НЕСИМВОЛОВ. Но это уже мелочи :-)

1. Удаляет пробелы в начале строки.

2. Вы забыли про то, что в имени файла может быть всё, что угодно, кроме нулевого байта и косой черты. Удаление всего, кроме буквенных символов, в принципе, нормальное решение. Кстати, мой скрипт не отрабатывает ситуации наличия в названии секции косой черты (что даёт возможность попытаться записать куда-нибудь в ../../.vimrc) и нулевого байта (но это уже не проблема с безопасностью). Впрочем, это легко добавить.

3. Относительно несимволов:

~/zsh - 1 (Created by format.vim)

(zyx:~/tmp/perl) % cat test-getopt2.pl | grep -v '^# ' #!/usr/bin/perl -p /^\s*!\s*(.*)/and open F,">$1"and next;print F $_; (zyx:~/tmp/perl) % cat test-getopt-drbatty.sed #!/bin/sed -rf $ a\ q /^ /!{ s/\W*(\w+)/\1/ h d } G s/\s*(.*)\n(.*)/s~.*~\1~w \2/]% (zyx:~/tmp/perl) % echo $'! coocoo\xFF\n \xFF\n \xFF\xFF' | ./test-getopt2.pl ! coocoo� �� (zyx:~/tmp/perl) % cat coocoo$'\377' �� (zyx:~/tmp/perl) % echo $'! coocoo\xFF\n \xFF\n \xFF\xFF' | ./test-getopt-drbatt y.sed �s~.*~~w coocoo� ��s~.*~~w coocoo� q


Ещё один минус sed’у.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
03.12.2010 22:37
1. Удаляет пробелы в начале строки.

это не баг, а фича.
ZyX писал(а):
03.12.2010 22:37
Ещё один минус sed’у.

это не баг, а фича. ваш перл просто не поддерживает UTF-8 по умолчанию. Например "Ф" это не буква с т.з. перла, а два байта. Включите поддержку UTF-8, и поймаете такой-же глюк.

Проверяется вот так:

Код: Выделить всё

doc@dt:~/tests$ echo -e "ABC\xD1XYZ" | sed '/^.*$/!a несимвол детектед!'
ABC�XYZ
несимвол детектед!
doc@dt:~/tests$ echo -e "ABCXYZ" | sed '/^.*$/!a несимвол детектед!'
ABCXYZ
Дело в том, что НЕСИМВОЛ не совпадает с точкой, от этого-то и проблемы.

Есть и такое решение:

Код: Выделить всё

doc@dt:~/tests$ export LC_CTYPE=C
doc@dt:~/tests$ export LC_COLLATE=C
doc@dt:~/tests$ echo -e "ABC\xD1XYZ" | sed '/^.*$/!a несимвол детектед!'
ABC�XYZ
doc@dt:~/tests$

Видите? Теперь sed работает как perl, т.е. несимволы исчезли.
Так имеет смысл делать для root'овой учётки, что-бы невозможно было взломать sed скрипты, которые запускаются с правами рута, подсунув туда несимвол. Примеры я уже приводил.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
03.12.2010 22:54
ZyX писал(а):
03.12.2010 22:37
1. Удаляет пробелы в начале строки.

это не баг, а фича.
ZyX писал(а):
03.12.2010 22:37
Ещё один минус sed’у.

это не баг, а фича. ваш перл просто не поддерживает UTF-8 по умолчанию. Например "Ф" это не буква с т.з. перла, а два байта. Включите поддержку UTF-8, и поймаете такой-же глюк.

Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
03.12.2010 23:26
Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.

хорошо. Где-то у нас тут была тема, в которой мы рассматривали ПРЕОБРАЗОВАНИЕ ТАКИХ СЛОВ Вот В Такие.
т.е. задача следующая: найти слова в верхнем регистре, и заменить все буквы в малые, кроме первых.

Код: Выделить всё

doc@dt:~/tests$ A="ЯЧСМИТЬБЮФЫВАПРОЛДЖЭЙЦУКЕНГШЩЗХЪЁ"
doc@dt:~/tests$ echo "ТЕСТ ТЕСТ ТЕСТ ТЕсТ ФФФФФ" | sed -r "s/\<([$A])([$A]+)\>/\1\L\2/g"
Тест Тест Тест ТЕсТ Ффффф

Как такое выглядит в вашем любимом perl'е? ;)
(обязательное условие - поддержка русского языка и UTF-8. Кроме того, "слова" вроде ZФ и вообще все не-русские заменять нельзя)
Я не сомневаюсь, границы слов есть и в PCRE, но работают-ли они для русских слов? Кроме того, совпадает-ли строка "Ф" с PCRE /\w/ ?

Насколько я знаю - да. Вот только ручками надо вбивать в скрипт кодировку, что плохо - PERL программа будет работать не везде, т.е. перед запуском придётся сначала узнать кодировку.

А если вы всё-же включите UTF-8, то вас поджидает проблема с несимволами (я не думаю, что разработчики perl настолько далеко отошли от логики. Дело в том, что по определению, точка совпадает с любым символом, что чисто по обычной, житейской логике, означает, что с несимволом точка не совпадает)

Кстати, результаты работы sed тоже являются строго одинаковыми, и всё это подробно описано в документации. Да и вообще: нету в коде Linux версии sed никакой обработки регулярных выражений (а следовательно - нет и багов), RE обрабатываются внутри glibc, потому, такое поведение будет и в программах на C или на любом другом ЯП.

Используя UTF-8 можно протащить вредоносный код через любой фильтр на регулярных выражениях, и всем это известно.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 00:08
ZyX писал(а):
03.12.2010 23:26
Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.

хорошо. Где-то у нас тут была тема, в которой мы рассматривали ПРЕОБРАЗОВАНИЕ ТАКИХ СЛОВ Вот В Такие.
т.е. задача следующая: найти слова в верхнем регистре, и заменить все буквы в малые, кроме первых.

Код: Выделить всё

doc@dt:~/tests$ A="ЯЧСМИТЬБЮФЫВАПРОЛДЖЭЙЦУКЕНГШЩЗХЪЁ"
doc@dt:~/tests$ echo "ТЕСТ ТЕСТ ТЕСТ ТЕсТ ФФФФФ" | sed -r "s/\<([$A])([$A]+)\>/\1\L\2/g"
Тест Тест Тест ТЕсТ Ффффф

Как такое выглядит в вашем любимом perl'е? ;)
(обязательное условие - поддержка русского языка и UTF-8. Кроме того, "слова" вроде ZФ и вообще все не-русские заменять нельзя)
Я не сомневаюсь, границы слов есть и в PCRE, но работают-ли они для русских слов? Кроме того, совпадает-ли строка "Ф" с PCRE /\w/ ?

Работают, совпадают, всё нормально.

Вот скрипт:

zyx@zyx-desktop

(zyx:~/tmp/perl) % echo "ТЕСТ ТЕСТ ТЕСТ ТЕсТ ФФФФФ" | perl -C -p -i -e 'BEGIN { use utf8; use feature "unicode_strings"; our $cul=''(?:(?=\p{Uppercase})\p{block:Cyrillic})''; } s/\b($cul)($cul+)\b/$1\L$2/g;' Тест Тест Тест ТЕсТ Ффффф



drBatty писал(а):
03.12.2010 22:54
Насколько я знаю - да. Вот только ручками надо вбивать в скрипт кодировку, что плохо - PERL программа будет работать не везде, т.е. перед запуском придётся сначала узнать кодировку.

Здесь согласен: либо у вас локаль utf8, либо у вас проблемы.

drBatty писал(а):
03.12.2010 22:54
А если вы всё-же включите UTF-8, то вас поджидает проблема с несимволами (я не думаю, что разработчики perl настолько далеко отошли от логики. Дело в том, что по определению, точка совпадает с любым символом, что чисто по обычной, житейской логике, означает, что с несимволом точка не совпадает)

Во-первых, если вы используете нормальные способы преобразования строки в utf8, несимвола у вас в ней быть не может. Во-вторых, точка с несимволом совпадает, даже если вы использовали самый нехороший способ (который просто говорит perl’у, что данная строка — utf8, но ничего не меняет).

drBatty писал(а):
03.12.2010 22:54
Кстати, результаты работы sed тоже являются строго одинаковыми, и всё это подробно описано в документации. Да и вообще: нету в коде Linux версии sed никакой обработки регулярных выражений (а следовательно - нет и багов), RE обрабатываются внутри glibc, потому, такое поведение будет и в программах на C или на любом другом ЯП.

То есть, ошибки в glibc ошибками не являются? Никакой разницы, где ошибка, нет, если сама ошибка есть.
Кроме того, такое поведение будет в любых программах на C или на любом другом ЯП если они используют движок от glibc.

drBatty писал(а):
03.12.2010 22:54
Используя UTF-8 можно протащить вредоносный код через любой фильтр на регулярных выражениях, и всем это известно.

Однако на perl можно почистить строку разными способами (Unicode::Normalize, Encode) и на выходе будет валидный utf8, а на sed?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 14:51
Во-первых, если вы используете нормальные способы преобразования строки в utf8, несимвола у вас в ней быть не может.

подразумевается, что у нас есть какой-то текст непонятно откуда (например из интернетов).
ZyX писал(а):
04.12.2010 14:51
Во-вторых, точка с несимволом совпадает, даже если вы использовали самый нехороший способ (который просто говорит perl’у, что данная строка — utf8, но ничего не меняет).

продемонстрируйте пожалуйста. И какой способ "хороший"? Вот есть у меня строка, например какая-то веб-страничка. Что я про неё знаю? Требуется, что-бы если в заголовке HTML было написано "UTF-8", то скрипт ОБЯЗАН корректно обработать эту страничку, не хуже чем если-бы это сделал я сам, через браузер. (конечно, если в страничке кодировка 1251, а написано UTF, то скрипт может и некорректно работать, а лучше - рухнуть с кодом ошибки).
ZyX писал(а):
04.12.2010 14:51
То есть, ошибки в glibc ошибками не являются? Никакой разницы, где ошибка, нет, если сама ошибка есть.
Кроме того, такое поведение будет в любых программах на C или на любом другом ЯП если они используют движок от glibc.

угу. только я не считаю это ошибкой (как и разработчики glibc), это документированная особенность.
ZyX писал(а):
04.12.2010 14:51
Однако на perl можно почистить строку разными способами (Unicode::Normalize, Encode) и на выходе будет валидный utf8, а на sed?

и на sed тоже можно. /^.*$/ истинно лишь для валидных строк. Чистить обычно не надо, достаточно зафиксировать факт ошибки (это обычно ошибка передачи либо атака, либо косорукость автора скрипта, либо - косорукость того, кто готовил исходные данные. В любом случае, это уже не задача для sed и perl)

При желании можно и отфильтровать (хотя в sed это довольно сложно).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 16:02
ZyX писал(а):
04.12.2010 14:51
Во-первых, если вы используете нормальные способы преобразования строки в utf8, несимвола у вас в ней быть не может.

подразумевается, что у нас есть какой-то текст непонятно откуда (например из интернетов).

При чём тут источник?

drBatty писал(а):
04.12.2010 16:02
ZyX писал(а):
04.12.2010 14:51
Во-вторых, точка с несимволом совпадает, даже если вы использовали самый нехороший способ (который просто говорит perl’у, что данная строка — utf8, но ничего не меняет).

продемонстрируйте пожалуйста. И какой способ "хороший"? Вот есть у меня строка, например какая-то веб-страничка. Что я про неё знаю? Требуется, что-бы если в заголовке HTML было написано "UTF-8", то скрипт ОБЯЗАН корректно обработать эту страничку, не хуже чем если-бы это сделал я сам, через браузер. (конечно, если в страничке кодировка 1251, а написано UTF, то скрипт может и некорректно работать, а лучше - рухнуть с кодом ошибки).

Способ уже демонстрировался: use feature "unicode_strings" + аргумент -C командной строки. Есть лучше, но длиннее: BEGIN{use Encode;}$_=Encode::decode_utf8($_) unless Encode::is_utf8($_); (часть начиная с unless можно проигнорировать, если вы точно знаете, что у $_ нет флага utf8).

Кстати, преобразованием какой-то странички в utf8 занимаются те библиотеки, которые и достают её из интернета, так что пока сервер корректно отдаёт заголовки всё нормально.

drBatty писал(а):
04.12.2010 16:02
ZyX писал(а):
04.12.2010 14:51
Однако на perl можно почистить строку разными способами (Unicode::Normalize, Encode) и на выходе будет валидный utf8, а на sed?

и на sed тоже можно. /^.*$/ истинно лишь для валидных строк. Чистить обычно не надо, достаточно зафиксировать факт ошибки (это обычно ошибка передачи либо атака, либо косорукость автора скрипта, либо - косорукость того, кто готовил исходные данные. В любом случае, это уже не задача для sed и perl)

Это точно задача для sed или perl: ничего не испортить.

drBatty писал(а):
04.12.2010 16:02
При желании можно и отфильтровать (хотя в sed это довольно сложно).

Как?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 16:50
При чём тут источник?

при том, что я говорю о случае, когда УЖЕ всё в UTF-8, и исходный текст, и скрипт, и кодировка системы.
ZyX писал(а):
04.12.2010 16:50
Кстати, преобразованием какой-то странички в utf8

причём тут "преобразование"? Ничего никуда преобразовывать не нужно.
ZyX писал(а):
04.12.2010 16:50
Это точно задача для sed или perl: ничего не испортить.

почему нет?
ZyX писал(а):
04.12.2010 16:50
Как?

да я уже и не помню, где-то у меня лежал такой скрипт, просто он мне НИ РАЗУ не пригодился, повторяю, достаточно зафиксировать ошибку, а выделять из мусора что-то полезное мне не нужно.

Ну если стоит задача написать действительно надёжный скрипт, при этом на входе может быть всё что угодно, то можно просто отказаться от UTF-8, ничего страшного, что "Ф" это не буква, а 2 байта - это обычно не мешает. Конечно можно и отфильтровать с отключённым UTF-8.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 17:04
ZyX писал(а):
04.12.2010 16:50
При чём тут источник?

при том, что я говорю о случае, когда УЖЕ всё в UTF-8, и исходный текст, и скрипт, и кодировка системы.

Тогда я вас вообще не понимаю. Проблемы ведь возникают, когда это не так.

drBatty писал(а):
04.12.2010 17:04
ZyX писал(а):
04.12.2010 16:50
Кстати, преобразованием какой-то странички в utf8

причём тут "преобразование"? Ничего никуда преобразовывать не нужно.

А как тогда быть с тем, что страница не в utf8?

drBatty писал(а):
04.12.2010 17:04
ZyX писал(а):
04.12.2010 16:50
Это точно задача для sed или perl: ничего не испортить.

почему нет?

?

drBatty писал(а):
04.12.2010 17:04
Ну если стоит задача написать действительно надёжный скрипт, при этом на входе может быть всё что угодно, то можно просто отказаться от UTF-8, ничего страшного, что "Ф" это не буква, а 2 байта - это обычно не мешает. Конечно можно и отфильтровать с отключённым UTF-8.

Не в случае, если нужно написать надёжный скрипт, которому надо знать, что есть буква.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 17:12
при том, что я говорю о случае, когда УЖЕ всё в UTF-8, и исходный текст, и скрипт, и кодировка системы.

Тогда я вас вообще не понимаю. Проблемы ведь возникают, когда это не так.

проблемы возникают если всё в UTF-8, но внутри текста имеется некорректный байт. Это приведёт к сбою sed, а вот про perl мне не понятно - у вас небыло сбоя лишь по той причине, что ваши скрипты работали НЕ в UTF-8. ИМХО.
ZyX писал(а):
04.12.2010 17:12
А как тогда быть с тем, что страница не в utf8?

для sed - никак. есть iconv для преобразования.
ZyX писал(а):
04.12.2010 17:12
Не в случае, если нужно написать надёжный скрипт, которому надо знать, что есть буква.

Я думаю, это будет сложно сделать на любом ЯП.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 17:27
ZyX писал(а):
04.12.2010 17:12
при том, что я говорю о случае, когда УЖЕ всё в UTF-8, и исходный текст, и скрипт, и кодировка системы.

Тогда я вас вообще не понимаю. Проблемы ведь возникают, когда это не так.

проблемы возникают если всё в UTF-8, но внутри текста имеется некорректный байт. Это приведёт к сбою sed, а вот про perl мне не понятно - у вас небыло сбоя лишь по той причине, что ваши скрипты работали НЕ в UTF-8. ИМХО.

Такое впечатление, что вы не читали мои сообщения.
ZyX писал(а):
03.12.2010 23:26
Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.


drBatty писал(а):
04.12.2010 17:27
ZyX писал(а):
04.12.2010 17:12
А как тогда быть с тем, что страница не в utf8?

для sed - никак. есть iconv для преобразования.
ZyX писал(а):
04.12.2010 17:12
Не в случае, если нужно написать надёжный скрипт, которому надо знать, что есть буква.

Я думаю, это будет сложно сделать на любом ЯП.

Что сложного в добавлении одной строчки для каждого внешнего источника? В зависимости от задачи, можно вообще обойтись одной строчкой на весь скрипт.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 18:00
Такое впечатление, что вы не читали мои сообщения.
Цитата(ZyX @ Dec 3 2010, в 23:26) *
Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.

читать-то я читал, но не согласился.
ZyX писал(а):
04.12.2010 18:00
Что сложного в добавлении одной строчки для каждого внешнего источника? В зависимости от задачи, можно вообще обойтись одной строчкой на весь скрипт.

а что скрывается за этой строчкой?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 18:29
ZyX писал(а):
04.12.2010 18:00
Такое впечатление, что вы не читали мои сообщения.
Цитата(ZyX @ Dec 3 2010, в 23:26) *
Точно такой же глюк я не поймаю: в зависимости от метода я получу либо какой-то строго определённый мусор (то есть результаты воспроизводимы, но смысла с моей точки зрения не несут) (кстати, имеющий длину ровно в один символ (не байт)) вместо неправильного байта, либо «\xFF» (+ предупреждение), либо знак вопроса. При желании можно заставить perl упасть, но в любом случае не существует такой строки, которая не соответствовала бы шаблону .*.

читать-то я читал, но не согласился.

С чем тут можно не согласиться? Здесь просто перечисление возможных эффектов от различных методов. Это всё равно, что не согласиться с тем, что в sed есть команда «s».

drBatty писал(а):
04.12.2010 18:29
ZyX писал(а):
04.12.2010 18:00
Что сложного в добавлении одной строчки для каждого внешнего источника? В зависимости от задачи, можно вообще обойтись одной строчкой на весь скрипт.

а что скрывается за этой строчкой?

Считает, что скрипт написан в utf8 и весь ввод-вывод тоже идёт в utf8, автоматически устанавливает флаг utf8 на все строки. Именно она преобразует байт 0xFF в «\xFF». Могут быть проблемы при работе с некоторыми пакетами, поэтому использование Encode для каждого внешнего источника и use utf8; предпочтительнее.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 20:05
С чем тут можно не согласиться? Здесь просто перечисление возможных эффектов от различных методов. Это всё равно, что не согласиться с тем, что в sed есть команда «s».

хотелось-бы лично убедиться :) например в том, что несимволы совпадают с точкой.
ZyX писал(а):
04.12.2010 20:05
Считает, что скрипт написан в utf8 и весь ввод-вывод тоже идёт в utf8, автоматически устанавливает флаг utf8 на все строки. Именно она преобразует байт 0xFF в «\xFF».

это ясно. но как это скажется на производительности и надёжности?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 20:56
ZyX писал(а):
04.12.2010 20:05
С чем тут можно не согласиться? Здесь просто перечисление возможных эффектов от различных методов. Это всё равно, что не согласиться с тем, что в sed есть команда «s».

хотелось-бы лично убедиться :) например в том, что несимволы совпадают с точкой.

В чём проблема?

zyx@zyx-desktop

(zyx:~/tmp/perl) % perl -e $'$_="\xFF"; print $_; utf8::upgrade($_); print $_; s/././g; print $_;' | hexdump -C 00000000 ff ff 2e |...| 00000003


(Замечу, что так делать нельзя. А если делать как можно, то несимволов не будет.)

drBatty писал(а):
04.12.2010 20:56
ZyX писал(а):
04.12.2010 20:05
Считает, что скрипт написан в utf8 и весь ввод-вывод тоже идёт в utf8, автоматически устанавливает флаг utf8 на все строки. Именно она преобразует байт 0xFF в «\xFF».

это ясно. но как это скажется на производительности и надёжности?

Производительность всего, что я писал, упиралась в IO. Надёжность не страдает от Encode, а с этой «одной строкой на скрипт» всё не так гладко: я один раз потратил кучу времени на то, чтобы понять, что директива use encoding "utf8"; является причиной очень неприятной ошибки.

Кстати, тоже и с pcre:

zyx@zyx-desktop

(zyx:tmp/image/xonotic) % echo $'\xFF' | grep -oP . | hexdump -C 00000000 ff 0a |..| 00000002

Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
04.12.2010 21:30
В чём проблема?

проблема вот в чём:

doc@dt:~/scripts$

perl -e $'$_="Ф\xD1B"; print $_; utf8::upgrade($_); print $_; s/./Z/g; print $_;' | hexdump -C 00000000 d0 a4 d1 42 d0 a4 d1 42 5a 5a 5a 5a |...B...BZZZZ| 0000000c


Как видите, ваша точка считает букву "Ф" за ДВА символа, а не за один. Потому конструкция s/// тут работает НЕ в UTF-8, потому и матчится точки. Если-бы s работала в UTF-8, то она-бы считала "Ф" одним символом, а не двумя.
ZyX писал(а):
04.12.2010 21:30
Кстати, тоже и с pcre:

Тот-же баг:

doc@dt:~/scripts$

echo "Ф" | grep -oP '.' | hexdump -C 00000000 d0 0a a4 0a |....| 00000004


Или "Ф" по вашему не один символ?

http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

drBatty писал(а):
04.12.2010 21:48
ZyX писал(а):
04.12.2010 21:30
В чём проблема?

проблема вот в чём:

doc@dt:~/scripts$

perl -e $'$_="Ф\xD1B"; print $_; utf8::upgrade($_); print $_; s/./Z/g; print $_;' | hexdump -C 00000000 d0 a4 d1 42 d0 a4 d1 42 5a 5a 5a 5a |...B...BZZZZ| 0000000c


Как видите, ваша точка считает букву "Ф" за ДВА символа, а не за один. Потому конструкция s/// тут работает НЕ в UTF-8, потому и матчится точки. Если-бы s работала в UTF-8, то она-бы считала "Ф" одним символом, а не двумя.

Упс. Я думал, это работает. Остальные известные мне методы не дадут получить невалидный utf8:

zyx@zyx-desktop

(zyx:tmp/image/xonotic) % perl -e $'$_="ФB"; utf8::decode($_) or die "decode failed"; s/./Z/g; print $_' ZZ% (zyx:tmp/image/xonotic) % perl -e $'$_="Ф\xFFB"; utf8::decode($_) or die "decode failed"; s/./Z/g; print $_' decode failed at -e line 1. (zyx:tmp/image/xonotic) % perl -e $'$_="Ф\xFFB"; use Encode; $_=Encode::decode_utf8($_); s/./Z/g; print $_;' ZZZ% (zyx:tmp/image/xonotic) % perl -e $'$_="Ф\xFFB"; use Encode; $_=Encode::decode_utf8($_); print $_;' | hexdump -C Wide character in print at -e line 1. 00000000 d0 a4 ef bf bd 42 |.....B| 00000006 (zyx:tmp/image/xonotic) % perl -e $'use encoding "utf8"; $_="Ф\xFFB"; s/./Z/g; print $_;' Malformed UTF-8 character (byte 0xff) at -e line 1. ZZZ% (zyx:tmp/image/xonotic) % perl -e $'use encoding "utf8"; $_="Ф\xFFB"; print $_;' | hexdump -C Malformed UTF-8 character (byte 0xff) at -e line 1. 00000000 d0 a4 00 42 |...B| 00000004


Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Прочитать файл до определённой строки

Сообщение ZyX »

ZyX писал(а):
04.12.2010 14:51
Здесь согласен: либо у вас локаль utf8, либо у вас проблемы.

Оказывается, можно и так, что проблем совсем не будет:

zyx@zyx-desktop

(zyx:~) % echo "Русский текст" | iconv -f UTF-8 | perl -p -i -e 'BEGIN {use open ":locale"}; use utf8; s/\p{InCyrillic}/й/g' ййййййй ййййй (zyx:~) % setopt rcquotes (zyx:~) % zsh -c 'export LANG="ru_RU.CP1251" ; echo "Русский текст" | iconv -f UTF-8 | perl -p -i -e ''BEGIN {use open ":locale"}; use utf8; s/\p{InCyrillic}/й/g''' | iconv -f cp1251 ййййййй ййййй


Надо было просто передвинуть use utf8 из BEGIN блока, спасибо daxim со stackoverflow.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

ZyX писал(а):
05.12.2010 22:17
Оказывается, можно и так, что проблем совсем не будет:

да, вроде такого более-менее нормально получается.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Dreamer77
Сообщения: 202
ОС: Debian, openSUSE, Mac OS X

Re: Прочитать файл до определённой строки

Сообщение Dreamer77 »

Не хотелось начинать новой темы, поэтому пишу здесь.
Первые посты в теме почти дали ответ на мой вопрос, но потом пошли дискуссии и обсуждение перла...

мой вопрос простой -- есть файл данных, организованный по принципу:
i=100
solutiontime=1e-3
1 100 200 500
2 200 300 700
4 234 645 234
i=100
solutiontime=2e-3
1 345 534 435
2 223 543 344
4 435 222 765
...
выдержан в таком стиле.
Мне требуется возможность выделить блок данных между "solutiontime=xxx" и следующим "i=yyy" по входному указанию "xxx".
Также может быть что этот блок в конце файла, т.ч. последующего "i=yyy" может не быть.
Хотелось бы иметь скрипт чтобы скопировать блок данных в другой файл.

Этото вопрос можно решить и на фортране (файл данных именно оттуда), но хотелось бы воспользоваться более простым способом.
Ubuntu-->Debian-->Gentoo-->openSUSE-> Mac OS X
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Прочитать файл до определённой строки

Сообщение drBatty »

Dreamer77 писал(а):
15.02.2011 13:44
Мне требуется возможность выделить блок данных между "solutiontime=xxx" и следующим "i=yyy" по входному указанию "xxx".
Также может быть что этот блок в конце файла, т.ч. последующего "i=yyy" может не быть.

Код: Выделить всё

sed -rn "/solutiontime=$xxx/,/i=[0-9]+/p" | sed -r '${ /i=[0-9]+/d; }'


Dreamer77 писал(а):
15.02.2011 13:44
Хотелось бы иметь скрипт чтобы скопировать блок данных в другой файл.

sed -iold_file
сохраняет старый файл с именем old_file. не совсем то, но вам понравится наверное :)
ну или просто sed "" old_file >new_file
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Прочитать файл до определённой строки

Сообщение watashiwa_daredeska »

awk -v t=1e-3 '$0==("soulutiontime=" t){p=1}/^i=/{p=0}p{print}'
Спасибо сказали: