Поток символов (нужно выделить только цифры)
Модератор: Модераторы разделов
-
newsrc
- Сообщения: 314
- ОС: Slackware
Поток символов
Есть поток случайных символов, к примеру:
1vkhu5XdlVv48x/gl5+66ruZj0yTjvhfTTvPs1IUTF/gUcm8jqXsmw9FmLpYFg2ZOuS7uG7DVEww
arnHjKwbnt+tQYVuhxk2wmMO2BD8OrH6UEGa3I67w4zgAhDug1S51N1DdoP///3vb/RUTm6wAg8/
Хочу из него только цифры, ну или буквы. Как? sed, awk........?????
P.S. На Си это заняло девять строк, но использовать для этого свой бинарник не хочется, нужен именно shell.
1vkhu5XdlVv48x/gl5+66ruZj0yTjvhfTTvPs1IUTF/gUcm8jqXsmw9FmLpYFg2ZOuS7uG7DVEww
arnHjKwbnt+tQYVuhxk2wmMO2BD8OrH6UEGa3I67w4zgAhDug1S51N1DdoP///3vb/RUTm6wAg8/
Хочу из него только цифры, ну или буквы. Как? sed, awk........?????
P.S. На Си это заняло девять строк, но использовать для этого свой бинарник не хочется, нужен именно shell.
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
nesk
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: Поток символов
echo "1vkhu5XdlVv48x/gl5+66ruZj0yTjvh" | sed s/[^0-9]//g
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Огромное спасибо за ответ.
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
Portnov
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Поток символов
Или
echo ... | tr -cd '[0-9]'
echo ... | tr -cd '[0-9]'
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Варианты, которые представили nesk и Portnov, не идентичны.
Вариант Портнова более корректный с точки зрения задачи извлечения цифр из потока -- вариант неска извлекает из потока не только цифры, но и разделители строк.
Но если уж совсем строго подходить к задаче, то ни один из предложенных вариантов не удовлетворяет требованию автора
Вариант Портнова более корректный с точки зрения задачи извлечения цифр из потока -- вариант неска извлекает из потока не только цифры, но и разделители строк.
Но если уж совсем строго подходить к задаче, то ни один из предложенных вариантов не удовлетворяет требованию автора
Т.к. в любом случае используется бинарник (sed или tr), который не является шелом.
-
sash-kan
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Поток символов
а так:
Код: Выделить всё
sed -n 's/[^0-9]//g;H;${x;s/\n//g;p}'Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
broom
- Бывший модератор
- Сообщения: 1629
- Статус: мизантроп.ка
- ОС: Gentoo
Re: Поток символов
а ещё вроде можно так
sed s/[^[:digit:]]//g
but in the darkness, behind your smile, you scream... © Dio
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Возможно здесь не слишком корректно было сказано. Как я отмечал выше, на Си написал программку, которая это делает. А изначально хотелось использовать, ну что ли, стандартные средства и минимизировать количество используемых программ.
И это работает. Думается более оптимально использовать именно этот вариант, дабы не вызывать дополнительные программы.
Это предопределённый диапазон символов, грубо говоря тоже, что и [0-9].
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Да, именно это я и имел ввиду. Т.е. в целом желание было понятно -- использовать существующую "стандартную" программу, а не писать свою.
Просто слова, что "нужен именно shell" можно понять как желание обойтись только командами стандартного шела (например /bin/bash). Может быть это и можно, но я пока не представляю как это сделать.
А вообще в линуксе (как варианте юникса) огромное число программ, которые позволяют решать очень много задач. Только изучить все их возможности ... часто получается, что быстрее написать свою, чем найти существующую (правда, не знаю, осталась ли программа mc, которая позволяла формировать многоколоночный текст).
А чем "более оптимально"?
Я пока не разобрался, что делает добавка ;H;${x;s/\n//g;p}, но по действию (на первый взгляд) вся эта команда работает также, как и более короткая
Код: Выделить всё
tr -cd '[0-9]'-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
MiK13 писал(а): ↑22.12.2008 16:21А чем "более оптимально"?
Я пока не разобрался, что делает добавка ;H;${x;s/\n//g;p}, но по действию (на первый взгляд) вся эта команда работает также, как и более короткая
Код: Выделить всё
tr -cd '[0-9]'
Это достаточно субъективно. Но если говорить конкретно о минимизации перечня используемых программ, то это выход. А с другой стороны
Код: Выделить всё
tr -cd '[0-9]'Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
drujebober
- Сообщения: 179
- ОС: Debian GNU/Linux lenny
Re: Поток символов
ну можно и шелом, zsh например:
$ p=";iashd;oih09e8w0-2384-98y8h4oiuh;ogi\nheq[0g983y2984yqp94-uq9438"
$ echo ${p//[^0-9]/}
09802384988409832984949438
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
drujebober писал(а): ↑22.12.2008 21:14ну можно и шелом, zsh например:
$ p=";iashd;oih09e8w0-2384-98y8h4oiuh;ogi\nheq[0g983y2984yqp94-uq9438"
$ echo ${p//[^0-9]/}
09802384988409832984949438
Пипец..... С Linux'ом не первый день работаю, но это - интересно!!!!
Linux люблю все больше и больше.......
А вот интересно по производительности, т.е. скорости обработки потока.... хотя такого рода статистика на первый взгляд ни кому не интересна, но всё же я попробую.... сравню приведённые варианты. Если кому интересна это никому ненужная затея
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
SLEDopit
- Модератор
- Сообщения: 4824
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Поток символов
ну на маленьких объемах разница минимальна, и как ни странно шелл самый быстрый.cent64 писал(а): ↑22.12.2008 23:28А вот интересно по производительности, т.е. скорости обработки потока.... хотя такого рода статистика на первый взгляд ни кому не интересна, но всё же я попробую.... сравню приведённые варианты. Если кому интересна это никому ненужная затеяотпишусь.... да и в любом случае отпишусь
Код: Выделить всё
[23:35]deb:~ $ p=";iashd;oih09e8w0-2384-98y8h4oiuh;ogi\nheq[0g983y2984yqp94-uq9438"
[23:35]deb:~ $ time echo ${p//[^0-9]/}
09802384988409832984949438
real 0m0.003s
user 0m0.000s
sys 0m0.000s
[23:36]deb:~ $ time echo $p|sed -n 's/[^0-9]//g;H;${x;s/\n//g;p}'
09802384988409832984949438
real 0m0.007s
user 0m0.004s
sys 0m0.004s
[23:35]deb:~ $ time echo $p|sed s/[^0-9]//g
09802384988409832984949438
real 0m0.013s
user 0m0.004s
sys 0m0.000s
[23:36]deb:~ $ time echo $p| tr -cd '[0-9]'
098023849884[09832984949438
real 0m0.021s
user 0m0.000s
sys 0m0.008sКод: Выделить всё
[23:46]deb:~ $ time echo $p|sed -n 's/[^0-9]//g;H;${x;s/\n//g;p}'>/dev/null
real 0m0.089s
user 0m0.064s
sys 0m0.012s
[23:46]deb:~ $ time echo $p| tr -cd '[0-9]'>/dev/null
real 0m0.067s
user 0m0.056s
sys 0m0.004s
[23:46]deb:~ $ time echo ${p//[^0-9]/}>/dev/null
real 1m7.652s
user 0m56.116s
sys 0m0.460sUNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
The more you believe you don't do mistakes, the more bugs are in your code.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Знакомое чувство
Немного не по теме.
Не так давно понадобилось создать скрипт (как стартовый шел юзера, т.е. он входит и выполняется только этот скрипт). Сохранить на флешке содержимое каталогов с данными в виде архима с именем ГГММДД_ЧЧММ.tgz, а как получить такое имя? В винде -- довольно просто (в 4NT), а как сформировать имя в bash'е?
И вдруг натыкаюсь на программу date, точнее, на её опцию + и оказывается, что в линуксе всё это делается на порядок проще:
Код: Выделить всё
tar cvfz `date +%y%m%d_%H%M`.tgz ...Ну, это не удивительно -- работает только и не тратится время на вызов других программ (sed и tr)
Но программы эти работают гораздо эффективнее.SLEDopit писал(а): ↑22.12.2008 23:38а вот на больших файлах картина кардинально меняется
Код: Выделить всё
[23:46]deb:~ $ time echo $p|sed -n 's/[^0-9]//g;H;${x;s/\n//g;p}'>/dev/null ...
Но у меня возникло 2 вопроса:
1. А что находится в $p в этом случае?
2. Как в случае шела читать данные из файла?
-
sash-kan
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Поток символов
эта добавка убирает символы \n.MiK13 писал(а): ↑22.12.2008 16:21Я пока не разобрался, что делает добавка ;H;${x;s/\n//g;p}, но по действию (на первый взгляд) вся эта команда работает также, как и более короткая
Код: Выделить всё
tr -cd '[0-9]'
выражение, наверно, можно упростить, если сначала собрать все строки в hold space, а потом убрать ненужное. только с точки зрения производительности это будет, наверно, худшее решение.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
sash-kan
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Поток символов
содержимое большого файла
да как угодно. хоть:
cat file|sed <args>
хоть
sed <args> file
хоть
sed <args> <file
хоть ещё как-нибудь поизвращённей.
или bash, например.drujebober писал(а): ↑22.12.2008 21:14ну можно и шелом, zsh например:
$ p=";iashd;oih09e8w0-2384-98y8h4oiuh;ogi\nheq[0g983y2984yqp94-uq9438"
$ echo ${p//[^0-9]/}
09802384988409832984949438
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
SLEDopit
- Модератор
- Сообщения: 4824
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Поток символов
там страшный набор симолов
Код: Выделить всё
[10:43]deb:~ $ echo $p
[23:43]deb:~ $ time echo $p|sed -n 's/[^0-9]//g;H;${x;s/\n//g;p}'>/dev/null real 0m0.024s user 0m0.004s sys 0m0.008s [23:43]deb:~ $ time echo $
{p//[^0-9]/}>/dev/null real 0m1.546s user 0m1.276s sys 0m0.000s [23:44]deb:~ $ time echo $p| tr -cd '[0-9]'>/dev/null real 0m0.013s user 0m0.008
s sys 0m0.004s [23:43]deb:~ $<..и в таком ключе достаточно приличный объем..>echo ${p//[^0-9]/}>/dev/null real 0m1.546s user 0m1.276s sys 0
m0.000s [23:44]deb:~ $ time echo $p| tr -cd '[0-9]'>/dev/null real 0m0.013s user 0m0.008s sys 0m0.004sя на нем и делал)
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
The more you believe you don't do mistakes, the more bugs are in your code.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Это я всё понимаю, но меня интересует немного другое:
Как только командами шела читать строки из файла в какую-то переменную?
Т.е. можно ли на шеле написать аналог программы
Код: Выделить всё
#include <stdio.h>
char s[256];
int main() {
FILE *f=fopen("aaa","r");
while(fgets(s,250,f))
fputs(s,stdout);
fclose(f);
}?
-
Portnov
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Поток символов
Построчно?
Или весь сразу?
А то, что вы написали - это урезанный аналог /bin/cat :)
Код: Выделить всё
cat $file | while read LINE
do ...
doneИли весь сразу?
Код: Выделить всё
content=$(cat $file)А то, что вы написали - это урезанный аналог /bin/cat :)
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Спасибо SLEDopit за приведённый тест.
Раз уж там были сравнены разные стандартные вещи, вот что сделал я:
Для наглядности:
geatf получился размеров в 37164K.
Результаты почти одинаковы по нескольким тестам.
clear_num - программка на Си, написанная только что за одну минуту.
Выводы:
1. Затратив на написание своей программки 60 сек и на обработку файла geatf 4,703 я получил полезное время работы 64 сек.
2. Использовав sed я потратил лишь 32 сек.
Т.е. я как хороший управленец, сделал капитальные затраты сегодня (я был даже в минусе), чтобы поиметь выгоду в последствии, т.е. потом я экономлю в 6,97 раза
.....
Вот бред... хе-хе
Раз уж там были сравнены разные стандартные вещи, вот что сделал я:
Для наглядности:
Код: Выделить всё
#cat /dev/urandom | uuencode -m - | tr -cd '[a-z,A-Z,0-9]' > geatfКод: Выделить всё
#time cat geatf | sed 's/[0-9]//g' >> /dev/null
real 0m32.826s
user 0m25.786s
sys 0m0.788s
#time cat geatf | ./clear_num >> /dev/null
real 0m4.703s
user 0m3.264s
sys 0m0.308sРезультаты почти одинаковы по нескольким тестам.
clear_num - программка на Си, написанная только что за одну минуту.
Выводы:
1. Затратив на написание своей программки 60 сек и на обработку файла geatf 4,703 я получил полезное время работы 64 сек.
2. Использовав sed я потратил лишь 32 сек.
Т.е. я как хороший управленец, сделал капитальные затраты сегодня (я был даже в минусе), чтобы поиметь выгоду в последствии, т.е. потом я экономлю в 6,97 раза
Вот бред... хе-хе
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Ну, эти результаты не совсем корректные -- надо ещё сравнить время, затраченное на изучение языка программирования и правил формирования програии со временем изучения возможностей программы sed (и получением информации о том, что вообще есть такая программа).
Но если говорить серьёзно, то в данном сдучае хотелось бы иметь результаты и такого варианта, как
Код: Выделить всё
tr -cd '[0-9]'Кстати, а будет ли разница между
Код: Выделить всё
cat geatf | sed 's/[0-9]//g' >> /dev/nullКод: Выделить всё
sed 's/[0-9]//g' < geatf >> /dev/null(и зачем к /dev/null добавлять данные?)
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Ну здесь можно ещё учесть время и ресурсы потраченные на литературу или интерент ресурсы, это уже через чур.....
Буду вечером дома сделаюMiK13 писал(а): ↑24.12.2008 01:55Но если говорить серьёзно, то в данном сдучае хотелось бы иметь результаты и такого варианта, какКод: Выделить всё
tr -cd '[0-9]'
А чтоб весь поток отфильтрованных символов на экран не слался....MiK13 писал(а): ↑24.12.2008 01:55Кстати, а будет ли разница между
иКод: Выделить всё
cat geatf | sed 's/[0-9]//g' >> /dev/null?Код: Выделить всё
sed 's/[0-9]//g' < geatf >> /dev/null
(и зачем к /dev/null добавлять данные?)
Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
Я не про это спрашивал. Зачем перед /dev/null два знака '>' ?
Кстати, по поводу перенаправления. В шелах 4DOS и 4NT с помощью команды setdos можно запретить перенаправление потока в файл, если он существует. На мой взгляд очень полезное средство, помогающее предотвратить случайное удаление нужного файла.
А в линуксовых шелах такая возможность есть?
-
nesk
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: Поток символов
man bash
Если используется оператор перенаправления > и с помощью встроенной команды set установлена опция noclobber, перенаправление не будет выполнено, если файл с соответствующим именем существует и является обычным файлом.
....
Это поведение также можно переопределить при создании выходных файлов, применяя оператор перенаправления |> вместо >.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Вот сравнение четырех вариантов:
Четвертым должен был быть shell, но у меня всё подвисло и я не дождался.
sed понятно почему так медленно.. Обрабатывает построчно, грузит в память он всё...., а мой мегафайл имел одну строку длиной в 38055936 символов..
А вот с tr и моей программкой, у которой цель - выводить только цифры, не совсем всё понятно.
Думается мой бредовый if..... можно сделать красивее
Код: Выделить всё
$ time cat geatf | sed 's/[^0-9]//g' > /dev/null
real 1m55.046s
user 1m21.457s
sys 0m1.860sКод: Выделить всё
$ time cat geatf | tr -cd [0-9] > /dev/null
real 0m0.804s
user 0m0.276s
sys 0m0.236sКод: Выделить всё
$ time cat geatf | ./clear_char > /dev/null
real 0m2.635s
user 0m2.044s
sys 0m0.284sЧетвертым должен был быть shell, но у меня всё подвисло и я не дождался.
sed понятно почему так медленно.. Обрабатывает построчно, грузит в память он всё...., а мой мегафайл имел одну строку длиной в 38055936 символов..
А вот с tr и моей программкой, у которой цель - выводить только цифры, не совсем всё понятно.
Думается мой бредовый if..... можно сделать красивее
Код: Выделить всё
#include <stdio.h>
main()
{
int c;
while((c = getchar()) != EOF)
if(c == '1' || c == '2' ||
c == '3' || c == '4' ||
c == '5' || c == '6' ||
c == '7' || c == '8' ||
c == '9' || c == '0')
putchar(c);
return 0;
}Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
cent64 писал(а): ↑24.12.2008 22:49Думается мой бредовый if..... можно сделать красивее
Код: Выделить всё
#include <stdio.h> main() { int c; while((c = getchar()) != EOF) if(c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' || c == '0') putchar(c); return 0; }
Что касается "бредового if"...
Надо учесть, что цифры в таблице расположены последовательно и поэтому можно вместо 10 сравнений использовать 2:
Код: Выделить всё
if((c>='0')&&(c<='9')) putchar(c);Второй вариант -- можно воспользоваться функцией isdigit или самому её реализовать: построить таблицу из 256 байьтов, в которой будут все нули и в элементы, номера которых соответствуют кодам цифр (или других требуемых знаков) занести 1. Тогда проверка будет
Код: Выделить всё
if(tr[c&255]) putchar(c);И, наконец, можно читать входной файл не по байтам (getchar), а сразу большими блоками в один буфер, а потом по указанной выше схеме байты, удовлетворяющие условию вывода, копировать в другой буфер, который и выводить после обработки всехо входного буфера
-
newsrc
- Сообщения: 314
- ОС: Slackware
Re: Поток символов
Обязательно попробую сегодня.
Вот только не совсем понятен смысл второго варианта, точнее реализация: что происходит здесь:В языке Си tr - это что?
Вот только не совсем понятен смысл второго варианта, точнее реализация: что происходит здесь:
Код: Выделить всё
if(tr[c&255]) putchar(c);Система -- это совокупность элементов и связей, дающая новые свойства, не присущие ни одному из элементов и ни одной из связей.
-
MiK13
- Сообщения: 1290
- ОС: Linux Debian
Re: Поток символов
cent64 писал(а): ↑25.12.2008 15:46Обязательно попробую сегодня.
Вот только не совсем понятен смысл второго варианта, точнее реализация: что происходит здесь:В языке Си tr - это что?Код: Выделить всё
if(tr[c&255]) putchar(c);
Нужно объявить
Код: Выделить всё
char tr[256] = {[0 ... 47] = 0, ['0' ... '9'] = 1, [58 ... 255] = 0};(правда, за синтаксис этого расширения си я тут не ручаюсь -- можно просто перечислить 48 нулей, потом 10 ненулей и оставшиеся нули, а данный вариант объявления, как и способ решения подобной задачи, я приводил в теме про определение номера самой левой единицы в байте)