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


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Перебор большого количества каталогов с извлечением нужных файлов по маске.  (Прочитано 2284 раз)

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

Оффлайн fierylion

  • Автор темы
  • Любитель
  • *
  • Сообщений: 54
  • fierylion
    • Просмотр профиля
    • www.folio.fierylion.ru
Ребята вот такая задача.
Предположим, есть каталог с различными документами.

Х смешно да, глядикась  дива какое.

В нем располагаются другие каталоги,  то есть вложенные в которые  в свою очередь вложены текстовые документы.
Каждый каталог начиная с материнского именуется  по типу  фамилия  в  нем каталог   дело в нутри  каталога дело  может быть   еще каталог предположим год и уже в нём документ текстового типа  по  маске     *.pdf    .
Однако  число вложенных каталогов  не одинаково.
Все файлы названы на родном  русском  языке,  естественно встречаются и такие имена типа
 
классный  файл.pdf – то есть с пробелами. Тоже  и с каталогами.

Задача  все эти каталоги  перебрать, что не так просто, так  как  их  несколько  тысяч, то есть в ручную это, тогда зачем придумали компьютеры, вытащив тот самый текстовый файл pdf  и  к его имени к имени текстового файла   прибавить  имена  всех каталогов по пути к нему.
Имя  файла должно выглядеть примерно так,  фамелия.дело.год.имя_файла.pdf
Затем файл  pdf  скопировать ,    cp  .  /путь назначения.
Может, кто сталкивался с аналогичной задачей подмогите.. Пжалусто.!!
Как работать  с пробельными именами каталогов и файлов?

Немного накалякал иначе не скажешь.
(Нажмите, чтобы показать/скрыть)

На форуме ЗАПРЕЩЕНО
2.4. Создавать темы с неинформативным названием, например «Помогите», «Пара вопросов», «Настройка Интернета» и т. п.

Убедительная просьба изменить название темы на более информативное.


--andrew_bye
« Последнее редактирование: 05 Январь 2012, 11:43:10 от fierylion »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: SHELL
« Ответ #1 : 05 Январь 2012, 09:23:16 »
прочти man find

Оффлайн fierylion

  • Автор темы
  • Любитель
  • *
  • Сообщений: 54
  • fierylion
    • Просмотр профиля
    • www.folio.fierylion.ru
find -name "*.pdf" -exec cp {} /home/user/terget \;

Вот что у меня вышло,  однако  это не решает проблему  с именами .

Оффлайн Sova777

  • Участник
  • *
  • Сообщений: 208
    • Просмотр профиля
    • Несколько слов о NetBeans C/C++ Pack'е
find(1) - Linux man page
...

-print0
    True; print the full file name on the standard output, followed by a null character (instead of the newline character that -print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.
Пользователь OpenSolaris 2008.11, Ubuntu 8.10, Windows XP. Mac OS X не нравится, стараюсь не использовать.

Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Код: (bash) [Выделить]
DIR="Документы" ; find "$DIR" -iname "*.pdf" | while read ; do echo cp "$REPLY" "$(echo $REPLY | sed 's/[ /]/_/g')" ; done

Оффлайн fierylion

  • Автор темы
  • Любитель
  • *
  • Сообщений: 54
  • fierylion
    • Просмотр профиля
    • www.folio.fierylion.ru
Спасибо  arcfi.
Но  всё ровно  немного не ясно.

Изначально создаём переменную, которая хранит  обрабатываемый каталог 
DIR=”Документы”
Далее следует знак перехода на новую строку.
За ним  непосредственно команда  find,  которая  принимает  только что созданию переменную в качестве пути  к  каталогу, где  ищет  файлы по  маске “*.pdf”

После чего всё найденное  передаётся оператором  |
В  тело цикла while  он,  на  сколько мне известно, будет работать пока условие  верно.

Следовательно, нужно задать это условия вместо  условия  используется     read

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

Сам размышляю так после  do   есho выводит в терминал надпись типа

cp   /здесь/полный/путь/до/файла/файл.pdf
 
далее следует тоже  путь,  но  sed  меняет  все знаки / на  _

Однако не могу понять с командой  сp   её синтаксис таков

сp  [опции могут  отсутствовать]  копируемое   ……  куда копируем

А в сценарии получается,  cp  “$REPLY” - то есть копируемое указано, верно, а вторая часть, куда, наверное,  воспринимается как  каталог, хотя  это просто путь  с заменёнными  / на _  поэтому копирование не происходит.

Собственно на выводе это и видно.

В том то вся и загвоздка как сформировать новое имя файла, его переименовать и затем его скопировать.
Может  сначала  просто все найденные файлы переименовать, а потом еще  раз пройтись и скопировать их.

И еще имя файла получается  таким  _home_user_путь_к_файлу.pdf
 
Мне нужно получить имя только от каталога  ./путь/ .. / .. /.pdf если я это делаю то имя выгладит  так, то есть оно становится  относительным.

._путь_к_файлу.pdf

то есть это имя  скрытого файла,  точка  впереди   файла делает его  скрытым.
Как ее убрать?

Нужно спросить,  как в редакторе  sed   удалить  первую точку  при этом все знаки / поменять  на  _ а последнею точку перед  расширением  файла не трогать?

Или же  просто удалить  часть ненужного имени,  которое во всех именах файлов будет одинаковым, так как путь до перебираемого каталога одинаков. Это наверное будет удобнее поскольку  в полученном сценарии можно просто менять  значения в переменой  хранящей в себе  путь.


Оффлайн ArcFi

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
fierylion,
1) цикл работает, пока find выдаёт строки
2) строки запоминаются в $REPLY
3) echo поставил для страховки
4) cp идёт без опций
5) первый аргумент для cp -- текущий путь до файла
6) второй аргумент -- требуемый путь
7) sed меняет символы в пути
8 ) чтобы в начале имён не было точек и подчёркиваний, сделайте так: sed 's/[ /]/_/g;s/^\.*_*//g'

Оффлайн fierylion

  • Автор темы
  • Любитель
  • *
  • Сообщений: 54
  • fierylion
    • Просмотр профиля
    • www.folio.fierylion.ru
Наконец  то  я решил проблему спасибо всем  кто помог мне.
Вот что у меня  получилось в итоге.

DIR="/home/user/lib/ney" ; DIRV="/home/user/lib_user/" ; find "$DIR" -iname "*.fb2" | while read ; do echo cp "$REPLY" "$DIRV""$(echo $REPLY | sed -e 's/\/home\/user\/lib\/ney\/*//' -e 's/[ /]/_/g')" ; done

Подробнее.
(Нажмите, чтобы показать/скрыть)
Что удивило.
"$(echo $REPLY | sed -e 's/\/home\/user\/lib\/ney\/*//' -e 's/[ /]/_/g')" – формирование  базового имени прямо в нутре  переменой это круто!!!

 

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