Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Прочитать файл, разбив каждую строку в массив  (Прочитано 5848 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Здравствуйте, подскажите, есть файл с такой структурой

id   picture
14   http://...img0.jpg
15   http://...img1.jpg
читаю файл так

file="list_picture"
while read line
do
  echo $line
  #здесь необходимо выполнить какие либо действия, например
  #wget -q -P `pwd` http://...img0.jpg -O 14.jpg
done < $file

т.е как разбить строку и подставить нужные значения?

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Попроще:
Код: (bash) [Выделить]
awk '{print $2}' urls.txt | wget -i-
Посложнее:
Код: (bash) [Выделить]
cat urls.txt | while read ; do wget "$(echo $REPLY | awk '{print $2}')" -O "$(echo $REPLY | awk '{print $1}').jpg" ; done
Вместо awk можно cut или bash-parameter-expansion.
« Последнее редактирование: 10 Декабрь 2011, 13:53:34 от arcfi »

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Спасибо))
первый вариант больше понравился
Код: (bash) [Выделить]
awk '{print "-q -P `pwd` "$2" -O "$1".jpg"}' list_picture | xargs -l wget
а как предусмотреть, если картинка с другим расширением?

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
а как предусмотреть, если картинка с другим расширением?
Думаю, придётся парсить второй столбец (url).
2-й вариант в этом смысле более легко масштабируем:
Код: (bash) [Выделить]
FILE_URL="$(echo $REPLY | awk '{print $2}')"
FILE_NAME_EXT="${URL##*.}"
FILE_NAME="${URL##*/}"

И кстати, в 1-м варианте можно обойтись без xargs. Cм. предыдущий пост.

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Только что прочитал что cut гораздо быстрее.. так что лучше cut))
Код: (bash) [Выделить]
cat list | while read ; do echo "$(cut -f2) $(cut -f1)"; doneвыведет только один столбец, c awk тоже самое  :-\

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Только что прочитал что cut гораздо быстрее.

Не всё, что пишут в интернетах, является правдой.
$ for i in {1..1000000} ; do echo "$i http://$i" ; done >>tmp.txt

$ time awk '{print $2}' tmp.txt >/dev/null

real 0m0.781s
user 0m0.739s
sys 0m0.036s

$ time cut -d' ' -f2 tmp.txt >/dev/null

real 0m2.789s
user 0m2.736s
sys 0m0.036s

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
у меня такой результат
$ time awk '{print $2}' tmp.txt >/dev/null

real 0m0.462s
user 0m0.432s
sys 0m0.032s

$ time cut -d' ' -f2 tmp.txt >/dev/null

real 0m0.260s
user 0m0.236s
sys 0m0.024s

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Сейчас ради интереса запустил на нескольких машинах на работе.
Оказалось, что результаты сильно зависят от версий утилит/дистрибутивов/ядра и железа.
Тем не менее, awk уверенно вырвался вперёд на 7 машинах из 8 тестируемых, в среднем обгоняя cut в 1,5-2,5 раза.

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Клёво)) значит awk ))
а как быть с тем что не работает второй вызов awk '{print $1} ?

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
а как быть с тем что не работает второй вызов awk '{print $1} ?
В смысле, не работает?
Надо посмотреть на сам файл.
od -c file | headТам могут быть виндовые концы строк или хитрые разделители.

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Re: Прочитать файл, разбив каждую строку в массив
« Ответ #10 : 10 Декабрь 2011, 18:09:29 »
Файл создаю так

Код: (bash) [Выделить]
mysql -u $user -p$pass -e "use $base; use book;select id,picture from book where picture!='' limit 2;" > list
$ od -c list | head
0000000   i   d  \t   p   i   c   t   u   r   e  \n   1   1   7   8   0
0000020   3   4  \t   h   t   t   p   :   /   /   b   i   g   .   j   p
0000040   g  \n
0000042

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Прочитать файл, разбив каждую строку в массив
« Ответ #11 : 10 Декабрь 2011, 18:50:03 »
У вас разделителем столбцов является символ табуляции.
В моей версии awk пробелы и табуляция по дефолту обрабатываются как разделители.
Возможно, у вас иначе.
Попробуйте так:
awk -F'[[:space:]]' ...
awk -F' |\t' ...
awk -F\\t ...
« Последнее редактирование: 10 Декабрь 2011, 18:53:37 от arcfi »

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Re: Прочитать файл, разбив каждую строку в массив
« Ответ #12 : 10 Декабрь 2011, 19:46:09 »
уже под вечер не соображаю, все примеры просто копировал в терминал и всё работает, а потом положил в файл

Код: (bash) [Выделить]
#!/bin/bash
cat list | while read ; do echo "$(awk '{print $2}')" ; done

и вылазит это ошибка
read: 2: arg count

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Прочитать файл, разбив каждую строку в массив
« Ответ #13 : 10 Декабрь 2011, 20:18:31 »
Код: (bash) [Выделить]
cat list | while read ; do echo "$(awk '{print $2}')" ; done
Строка читается в "$REPLY".

Оффлайн iormark

  • Автор темы
  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
Re: Прочитать файл, разбив каждую строку в массив
« Ответ #14 : 11 Декабрь 2011, 09:35:05 »
Спасибо)) у меня вот так заработало
Код: (bash) [Выделить]
cat list | while read REPLY; do echo "$(echo $REPLY | awk '{print $2}') $(echo $REPLY | awk '{print $1}')"; done

Пользователь решил продолжить мысль 11 Декабрь 2011, 09:53:43:
Заработало  :)

Код: (bash) [Выделить]
cat list | while read REPLY; do
  URL="$(echo $REPLY | awk '{print $2}')"
  EXT="${URL##*.}"
  wget -q -P `pwd` $URL -O $(echo $REPLY | awk '{print $1}')"."$EXT;
done
« Последнее редактирование: 11 Декабрь 2011, 09:53:43 от iormark »

 

Страница сгенерирована за 0.092 секунд. Запросов: 25.