LINUX.ORG.RU

sed


0

0

Нужно сделать так:

есть файлы со следующими характеристиками: ------------------------------------------------------- меняющееся сочетание символов - мусор(количество строчек тоже разное) неизменяемое ( повторяющееся во всех файлах) данные (различные) -------------------------------------------------------

Нужно вырезать меняющееся сочетание до неизменяемого,а остальное неизменяемые данные и данные оставить.Помогите.

долго пытался понять - не получилось :)

SadStork
()

ага я тоже что то не въехал :)

можно чуть помедленее и по внятней :)

White_Skull
()

Чуваки, LinReader над вам издевается

anonymous
()

perl -pi -e 's/^-{$minconst,}$/"-" x $const /e' <filename(s)> -- так что-ли?

anonymous
()

(Пояснение к предыдущему сообщению):

Правильно ли я понял, что нужно заменить в строках состоящих из одних дефисов переменное количество дефисов на постоянное?

anonymous
()

О чем здесь вообще речь ??? ;)

Olya
()

user line breaks должны быть первым шагом на пути к пониманию

dilmah ★★★★★
()

Объясняю:

есть файлы,вначале идёт мусор(заголовок из другого типа),а потом данные.Нужно этот заголовок с мусором отрезать.Данные начинаются со стандартных строчек во всех файлах,по которым можно найти точку собреза ненужной информации в файле.То есть например:

!"*#:*:: Gif *** ***

- всё до Gif надо обрезать - gif сочетание,которое есть всегда.Надеюсь мне здесь помогут.

LineReader
() автор топика

P.S. - просто форматиролвание в моём первом постинге съехало,сорри.

LineReader
() автор топика

Если предположить, что в файле только один подобный образец и далее нужен вывод до конца файла (и что сам файл разумной ограниченной длины), так вот, с учетом всех этих предположений я бы использовал grep. Например: grep -A1000000000 <образец> <файл>. Ничего страшного, если образец будет в строках выводимых по опции -А. Но вот если самих строк больше миллиарда... (годится любое 32-битовое целое). А если еще в оставшихся строках образец второй раз попадется...

anonymous
()

То есть я даю комманду grep -A1000000000 <GIF> и она обрезает данные?А что такое -A1000000000?

LineReader
() автор топика

>Правильно ли я понял, что нужно заменить в строках состоящих из одних дефисов переменное количество дефисов на постоянное?

Просто нужно вырезать мусор до константных строчек,мусор разный.

LineReader
() автор топика

Предыдущее сообщение прошу считать недействительным. Способ с grep мне больше не нравится. На любом достаточно большом файле (у Вас ведь много файлов состоящих из нескольких миллиардов строк, не так ли?) он даст ошибку. Предлагается другой способ: awk '{if(/<образец>/)a=999; if(a==999) print}' <имяфайла>. Можно для пущего спокойствия добавить BEGIN {a=0}, только и без того все будет работать

anonymous
()

-A<большоечисло> просто означает -- печатать строчку с образцом и это число строк за ней. Если это число заведомо больше числа строк в файле, то "печатать файл до конца"

anonymous
()

(Последние два варианта я посылал в предположении, что нужно печатать начиная со строки с указанным образцом (при этом угловые скобки это часть метатермина "образец", а не часть синтаксиса команды) и до конца файла. Возможно я опять что-то не так понял. Я туповат от природы

anonymous
()

tail -n$(($(nl -ba -nln info.txt | tail -n1 | cut -d' ' -f1) - $(nl -ba -nln info.txt | grep pattern_GIF | tail -n1 | cut -d' ' -f1) + 1)) info.txt

dilmah ★★★★★
()

Блеск. Только при желании можно еще лучше запутать. И должно быть -d' ' , а не просто -d. Для тех кто не желает разбираться с длинными цепочками команд подсказка: nl -ba -nln info.txt | tail -n1 | cut -d' ' -f1 -- это просто wc -l

anonymous
()

И, кстати, 2 замечания: Во-первых, проблема больших файлов остается, во-вторых если образец встречается несколько раз результат будет неверным. Лучше использовать head -1 вместо последнего tail

anonymous
()

:) а фишка в том что это не просто wc -l

на cygwin wc -l info.txt выдаст

1234 info.txt

я не знаю нарушает это позикс или нет, но жизнь усложняет

dilmah ★★★★★
()

Даже без cut -- cat info.txt | wc -l. Я понимаю, конечно, что между cut и cat ровно одна буква разницы...

anonymous
()

sed -n /Gif/p
Отрубит весь мусор до первого встречного gif.

rihad
()

Спасибо,буду испытывать :-)

LineReader
() автор топика

Re

>sed -n /Gif/p >Отрубит весь мусор до первого встречного gif.

Составил такой скрипт:

---------------------------------------- #!/bin/sh

pattern='jpeg'

for file in `ls *.jpg -1 ` do

sed -n /$pattern/p > $file.jpg

done --------------------------------------- подвисает,а вфайле *.jpg ничего нет...

LineReader
() автор топика

Re

>>>tail -n$(($(nl -ba -nln info.txt | tail -n1 | cut -d' ' -f1) - $(nl -ba -nln info.txt | grep pattern_GIF | tail -n1 | cut -d' ' -f1) + 1)) info.txt

На текстовых отлично работает,а вот на бинарных всё остайтся без изменений.Вот мой скрипт:

-------------------------------------- #!/bin/sh

pattern='GIF'

for file in `ls * -1 ` do

tail -n$(($(nl -ba -nln $file | tail -n1 | cut -d' ' -f1) - $(nl -ba -nln $file | grep $pattern | tail -n1 | cut -d' ' -f1) + 1)) $file > $file.gif

done ------------------------------------

LineReader
() автор топика

Не подвисает, а ждет ввода.
Попробуй
sed -n /$pattern/p < $file.jpg > $file.jpg.new
mv -f $file.jpg.new $file.jpg

rihad
()

LineReader, строчка с nl была не более чем шуткой. Я сомневаюсь, что автор предполагал, что кто-то реально попробует ее использовать

anonymous
()

Вопрос к rihad'у: sed -n /<образец>/p выведет только строчки содержащие образец. А отнюдь не все строчки до конца файла. Что, как я понимаю, LineReader'у не нужно. Хотя... Варианты c grep и awk ему как-то не понравились.

anonymous
()

Re

>Варианты c grep и awk ему как-то не понравились.

-------------- #!/bin/sh

pattern='GIF'

for file in `ls -1 *` do

awk '{if(/<$pattern>/)a=999; if(a==999) print}' $file

done ------------ - Оставляет все файлы без изменений

--------------

#!/bin/sh

pattern='GIF'

for file in `ls -1 *` do

grep -A1000000000 -U $pattern $file > $file.jpg

done ----------------

На бинарных файлах при фильтрации пишет(у меня бинарные файлы):

Binary file 00002429 matches - Вообще двоичные файлы этот скрипт фильтрует прекрасно,но вот файлы у меня то бинарные...

... >LineReader, строчка с nl была не более чем шуткой. Я сомневаюсь, что автор предполагал, что кто-то реально попробует ее использовать

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

LineReader
() автор топика

Во-первых, по поводу awk. Я уже писал, что угловые скобки не нужны. pattern='GIF'; for file in * ; do awk '{if(/$pattern/)a=999; if(a==999) print}' $file ; done

Во-вторых, строка с nl явно была намеренно усложнена до предела (Там же русским языком написано, что nl -ba -nln info.txt | tail -n1 | cut -d' ' -f1 это АБСОЛЮТНО то же самое, что и wc -l < info.txt только длиннее и непонятнее). Это такое развлечение -- писать длинные и непонятные командные строки, которые, тем не менее, делают то, что от них требуется. Правда медленно (это цена за непонятность). И, кстати, это свидетельство хорошего знания утилит Unix, потому что мне бы, например, и в голову не пришло соорудить такую строчку из tail и nl

anonymous
()

И, кстати, по поводу "человек просит помощи,а над ним прикалываются". Исходный вопрос был сформулирован так, что кое-кто из нас считал, что человек не просит помощи, а сам прикалывается - "Чуваки, LinReader над вам издевается". А потом dimah отправил свое сообщение, когда (на мой взгляд) ответ на фактически заданный вопрос уже был получен. Причем не один. В конце концов, форум существует не только для того чтобы отвечать на вопросы. Я вот, например для себя подчерпнул из его командной строки кое-что новое.

anonymous
()

Двоичные/бинарные/текстовые я не комментирую...

anonymous
()

Не подвисает, а ждет ввода. Попробуй sed -n /$pattern/p < $file.jpg > $file.jpg.new mv -f $file.jpg.new $file.jpg

rihad
()

Не подвисает, а ждет ввода. Попробуй sed -n /$pattern/p < $file.jpg > $file.jpg.new mv -f $file.jpg.new $file.jpg

rihad
()

Re

>>pattern='GIF'; for file in * ; do awk '{if(/$pattern/)a=999; if(a==999) print}' $file ; done

Ничего не делает - файлы какими были,такими и остаются..

>Двоичные/бинарные/текстовые я не комментирую...

Это например вы решили спаять радиоприставку для компьютера,и вы не радиотехник.Вполне возможно вы где-то ошибётесь.А вам - "а мы не комментируем,учите мат часть" - "Так она же большая,а я новичок" - "...",".."

>ответ на фактически заданный вопрос уже был получен. Причем не один.

И ни один не работает..

>В конце концов, форум существует не только для того чтобы отвечать на вопросы.

Это ваше право,как вести себя на форуме.Не хотите помочь,не помагайте.

Решения к сожалению я здесь пока не нашёл - файлы как были не отредактироваными,так и остались...

LineReader
() автор топика

Прошу прощения, я хотел написать

sed -n /$pattern/,\$p

но в последний момент глюкнул и написал совсем другое.
Эта команда пропустит весь инпут вплоть до первого встречного $pattern. Если не ошибаюсь, только GNU sed.

rihad
()

я честно не прикалывался. Просто я увидел что wc -l file не то выдает и уже не стал думать в этом направлении а в интересах consistency сделал первое выражение такого же типа как и второе.

dilmah ★★★★★
()

Черт, я идиот. Оставляя в стороне недопустимый тон LineReader'a (надо будет его запомнить и больше на его вопросы не отвечать). Случайно я не заметил очевидную ошибку -- переменная $pattern была установлена как переменная bash, а использовалась как переменная awk. Которая, ясное дело, не существует. правильная строчка должна выглядеть так:

pattern='GIF'; for file in * ; do awk -v pattern=$pattern '{if(/$pattern/)a=3; if(a==3) print}' $file ; done

или короче:

for file in * ; do awk '{if(/GIF/)a=3; if(a==3) print}' $file ; done

(цифры, понятно, выбираются произвольно)

anonymous
()

Re

>Попробуй sed -n /$pattern/p < $file.jpg > $file.jpg.new mv -f $file.jpg.new $file.jpg

- Выводит в файл тольку строчку,содержащую паттерн,а данные,следующие за строчкой не выводит..

LineReader
() автор топика

а я не понимаю почему это не работает на бинарных файлах, первую строку вывода еще надо дополнительно sed'ом обработать помоему и все.

dilmah ★★★★★
()

Re

>for file in * ; do awk '{if(/GIF/)a=3; if(a==3) print}' $file ; done

-- Сработало,как часы.

>Оставляя в стороне недопустимый тон LineReader'a (надо будет его запомнить и больше на его вопросы не отвечать)

Вообще я очень не люблю хамства - ни со своей стороны,ни с чужой.А манеру разговора вы выбрали - простите,если что-то не так...

LineReader
() автор топика

Re

Благодарю всех,кто мне помог,или пытался помочь..

LineReader
() автор топика

Исправленный вариант с sed на мой взгляд был самым удачным (Кстати я и сам собирался заменить awk на sed, но не успел -- на perl и awk можно писать с хода, а sed знать надо...).

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