Решено: Копирование файлов с определенным расширением.

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС для молодых и начинающих системных администраторов.

Модератор: SLEDopit

Ответить
Аватара пользователя
Rassol2
Сообщения: 120

Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

Здравствуйте.
Хоть вы подскажите какой командой можно скопировать все файлы с определенным расширением.
То есть есть директория в которой куча хлама, и куча директорий в которых опять же директории и хлам.

Мне нужно сделать скрипт который будет копировать с этой директории все файлы имеющие расширение mp3 mp4 avi
Пример

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

/home/rassol2/dir1/dir2/dir3/dima.mp3 dima.avi dima.mp4 rgr.txt ooo.sh - (И всякое ненужное)

теперь мне нужно скопировать это

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

cp -ru /home/rassol2/ /home/rassol2/beckup

В этом случаи копируется содержимое dir1 со всеми папками и файлами. Но нужно тока с папками и файлами определенного расширения.

В итоге нужно получить

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

/home/rassol2/beckup/dir1/dir2/dir3/dima.mp3 dima.avi dima.mp4

без лишних rgr.txt ooo.sh

За ранние спс.
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: Решено: Копирование файлов с определенным расширением.

Сообщение liaonau »

Что-то вроде

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

rsync -r -f "+ */" -f "+ **.mp3" -f "+ **.avi" -f "+ **.mp4" -f "- *" /откуда/ /куда
Спасибо сказали:
Аватара пользователя
Rassol2
Сообщения: 120

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

Это как раз то что мне нужно с малыми недостатками, но то что нужно )))
Оно создало сетку директорий даже если в них нету нужных форматов.
Но это уже шаг. Во истину благодарен !!!
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: Решено: Копирование файлов с определенным расширением.

Сообщение liaonau »

Опция -m, она же --prune-empty-dirs
Вообще, почитайте man rsync.
Спасибо сказали:
Аватара пользователя
Rassol2
Сообщения: 120

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

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

rsync -rm -f "+ */" -f "+ **.mp3" -f "+ **.avi" -f "+ **.mp4" -f "- *" /откуда/ /куда

тока и при присутствии ключа m тоже копируются все директории даже если в них нету нужных расширений.
man по rsync там как правила ключи и примеры работы для создание бекапов, и что то я не смог разобраться как записать ключи для выполнение этой задачи.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Решено: Копирование файлов с определенным расширением.

Сообщение drBatty »

Rassol2 писал(а):
17.05.2012 02:02
Мне нужно сделать скрипт который будет копировать с этой директории все файлы имеющие расширение mp3 mp4 avi

решение:

$

find \( -name "*.mp3" -o -name "*.mp4" -o -name "*.avi" \) -exec cp --parents -v -t target_dir/ {} +


liaonau писал(а):
17.05.2012 02:38
Что-то вроде
Код
rsync

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

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

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

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

find \( -name "*.mp3" -o -name "*.mp4" -o -name "*.avi" \) -exec cp --parents -v -t target_dir/ {} +

Но с rsync было понятнее. А где здесь указывать откуда и куда ?
Спасибо сказали:
Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Ленивая Бестолочь »

Rassol2 писал(а):
18.05.2012 01:56
find \( -name "*.mp3" -o -name "*.mp4" -o -name "*.avi" \) -exec cp --parents -v -t target_dir/ {} +

target_dir -- это откуда.
{} -- это куда.
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Решено: Копирование файлов с определенным расширением.

Сообщение drBatty »

Ленивая Бестолоч... писал(а):
18.05.2012 02:24
target_dir -- это откуда.
{} -- это куда.

перед написанием ерунды ознакомьтесь с man cp
cp [OPTION]... -t DIRECTORY SOURCE...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: Решено: Копирование файлов с определенным расширением.

Сообщение drBatty »

Rassol2 писал(а):
18.05.2012 01:56
А где здесь указывать откуда и куда ?

для ускорения команды желательно, что-бы одна cp копировала сразу группу файлов. для этого есть специальный синтаксис:

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

cp -t каталог_КУДА_копируем файл1 файл2 файл3 файл4...


--parents нужно для того, что-бы при копировании ./dir1/dir2/file1 автоматически создавались target_dir/dir1 и target_dir/dir1/dir2.

ну и наконец, + в find пихает все найденные файлы в хвост команды (файл1 файл2 файл3 файл4...). (точнее обычно все, если они влезают)
Rassol2 писал(а):
18.05.2012 01:56
Но с rsync было понятнее.

конечно, всего-то осилить
Spoiler
FILTER RULES
The filter rules allow for flexible selection of which files to transfer (include) and which files to skip
(exclude). The rules either directly specify include/exclude patterns or they specify a way to acquire
more include/exclude patterns (e.g. to read them from a file).

As the list of files/directories to transfer is built, rsync checks each name to be transferred against
the list of include/exclude patterns in turn, and the first matching pattern is acted on: if it is an
exclude pattern, then that file is skipped; if it is an include pattern then that filename is not skipped;
if no matching pattern is found, then the filename is not skipped.

Rsync builds an ordered list of filter rules as specified on the command-line. Filter rules have the fol‐
lowing syntax:

RULE [PATTERN_OR_FILENAME]
RULE,MODIFIERS [PATTERN_OR_FILENAME]

You have your choice of using either short or long RULE names, as described below. If you use a
short-named rule, the ’,’ separating the RULE from the MODIFIERS is optional. The PATTERN or FILENAME
that follows (when present) must come after either a single space or an underscore (_). Here are the
available rule prefixes:

exclude, - specifies an exclude pattern.
include, + specifies an include pattern.
merge, . specifies a merge-file to read for more rules.
dir-merge, : specifies a per-directory merge-file.
hide, H specifies a pattern for hiding files from the transfer.
show, S files that match the pattern are not hidden.
protect, P specifies a pattern for protecting files from deletion.
risk, R files that match the pattern are not protected.
clear, ! clears the current include/exclude list (takes no arg)

When rules are being read from a file, empty lines are ignored, as are comment lines that start with a
"#".

Note that the --include/--exclude command-line options do not allow the full range of rule parsing as
described above -- they only allow the specification of include/exclude patterns plus a "!" token to clear
the list (and the normal comment parsing when rules are read from a file). If a pattern does not begin
with "- " (dash, space) or "+ " (plus, space), then the rule will be interpreted as if "+ " (for an
include option) or "- " (for an exclude option) were prefixed to the string. A --filter option, on the
other hand, must always contain either a short or long rule name at the start of the rule.

Note also that the --filter, --include, and --exclude options take one rule/pattern each. To add multiple
ones, you can repeat the options on the command-line, use the merge-file syntax of the --filter option, or
the --include-from/--exclude-from options.

INCLUDE/EXCLUDE PATTERN RULES
You can include and exclude files by specifying patterns using the "+", "-", etc. filter rules (as intro‐
duced in the FILTER RULES section above). The include/exclude rules each specify a pattern that is
matched against the names of the files that are going to be transferred. These patterns can take several
forms:

o if the pattern starts with a / then it is anchored to a particular spot in the hierarchy of files,
otherwise it is matched against the end of the pathname. This is similar to a leading ^ in regular
expressions. Thus "/foo" would match a name of "foo" at either the "root of the transfer" (for a
global rule) or in the merge-file’s directory (for a per-directory rule). An unqualified "foo"
would match a name of "foo" anywhere in the tree because the algorithm is applied recursively from
the top down; it behaves as if each path component gets a turn at being the end of the filename.
Even the unanchored "sub/foo" would match at any point in the hierarchy where a "foo" was found
within a directory named "sub". See the section on ANCHORING INCLUDE/EXCLUDE PATTERNS for a full
discussion of how to specify a pattern that matches at the root of the transfer.

o if the pattern ends with a / then it will only match a directory, not a regular file, symlink, or
device.

o rsync chooses between doing a simple string match and wildcard matching by checking if the pattern
contains one of these three wildcard characters: ’*’, ’?’, and ’[’ .

o a ’*’ matches any path component, but it stops at slashes.

o use ’**’ to match anything, including slashes.

o a ’?’ matches any character except a slash (/).

o a ’[’ introduces a character class, such as [a-z] or [[:alpha:]].

o in a wildcard pattern, a backslash can be used to escape a wildcard character, but it is matched
literally when no wildcards are present.

o if the pattern contains a / (not counting a trailing /) or a "**", then it is matched against the
full pathname, including any leading directories. If the pattern doesn’t contain a / or a "**",
then it is matched only against the final component of the filename. (Remember that the algorithm
is applied recursively so "full filename" can actually be any portion of a path from the starting
directory on down.)

o a trailing "dir_name/***" will match both the directory (as if "dir_name/" had been specified) and
everything in the directory (as if "dir_name/**" had been specified). This behavior was added in
version 2.6.7.

Note that, when using the --recursive (-r) option (which is implied by -a), every subcomponent of every
path is visited from the top down, so include/exclude patterns get applied recursively to each subcompo‐
nent’s full name (e.g. to include "/foo/bar/baz" the subcomponents "/foo" and "/foo/bar" must not be
excluded). The exclude patterns actually short-circuit the directory traversal stage when rsync finds the
files to send. If a pattern excludes a particular parent directory, it can render a deeper include pat‐
tern ineffectual because rsync did not descend through that excluded section of the hierarchy. This is
particularly important when using a trailing ’*’ rule. For instance, this won’t work:

+ /some/path/this-file-will-not-be-found
+ /file-is-included
- *

This fails because the parent directory "some" is excluded by the ’*’ rule, so rsync never visits any of
the files in the "some" or "some/path" directories. One solution is to ask for all directories in the
hierarchy to be included by using a single rule: "+ */" (put it somewhere before the "- *" rule), and per‐
haps use the --prune-empty-dirs option. Another solution is to add specific include rules for all the
parent dirs that need to be visited. For instance, this set of rules works fine:

+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *

Here are some examples of exclude/include matching:

o "- *.o" would exclude all names matching *.o

o "- /foo" would exclude a file (or directory) named foo in the transfer-root directory

o "- foo/" would exclude any directory named foo

o "- /foo/*/bar" would exclude any file named bar which is at two levels below a directory named foo
in the transfer-root directory

o "- /foo/**/bar" would exclude any file named bar two or more levels below a directory named foo in
the transfer-root directory

o The combination of "+ */", "+ *.c", and "- *" would include all directories and C source files but
nothing else (see also the --prune-empty-dirs option)

o The combination of "+ foo/", "+ foo/bar.c", and "- *" would include only the foo directory and
foo/bar.c (the foo directory must be explicitly included or it would be excluded by the "*")

The following modifiers are accepted after a "+" or "-":

o A / specifies that the include/exclude rule should be matched against the absolute pathname of the
current item. For example, "-/ /etc/passwd" would exclude the passwd file any time the transfer
was sending files from the "/etc" directory, and "-/ subdir/foo" would always exclude "foo" when it
is in a dir named "subdir", even if "foo" is at the root of the current transfer.

o A ! specifies that the include/exclude should take effect if the pattern fails to match. For
instance, "-! */" would exclude all non-directories.
o A C is used to indicate that all the global CVS-exclude rules should be inserted as excludes in
place of the "-C". No arg should follow.

o An s is used to indicate that the rule applies to the sending side. When a rule affects the send‐
ing side, it prevents files from being transferred. The default is for a rule to affect both sides
unless --delete-excluded was specified, in which case default rules become sender-side only. See
also the hide (H) and show (S) rules, which are an alternate way to specify sending-side
includes/excludes.

o An r is used to indicate that the rule applies to the receiving side. When a rule affects the
receiving side, it prevents files from being deleted. See the s modifier for more info. See also
the protect (P) and risk ® rules, which are an alternate way to specify receiver-side
includes/excludes.

o A p indicates that a rule is perishable, meaning that it is ignored in directories that are being
deleted. For instance, the -C option’s default rules that exclude things like "CVS" and "*.o" are
marked as perishable, and will not prevent a directory that was removed on the source from being
deleted on the destination.

MERGE-FILE FILTER RULES
You can merge whole files into your filter rules by specifying either a merge (.) or a dir-merge (:) fil‐
ter rule (as introduced in the FILTER RULES section above).

There are two kinds of merged files -- single-instance (’.’) and per-directory (’:’). A single-instance
merge file is read one time, and its rules are incorporated into the filter list in the place of the "."
rule. For per-directory merge files, rsync will scan every directory that it traverses for the named
file, merging its contents when the file exists into the current list of inherited rules. These
per-directory rule files must be created on the sending side because it is the sending side that is being
scanned for the available files to transfer. These rule files may also need to be transferred to the
receiving side if you want them to affect what files don’t get deleted (see PER-DIRECTORY RULES AND DELETE
below).

Some examples:

merge /etc/rsync/default.rules
. /etc/rsync/default.rules
dir-merge .per-dir-filter
dir-merge,n- .non-inherited-per-dir-excludes
:n- .non-inherited-per-dir-excludes

The following modifiers are accepted after a merge or dir-merge rule:

o A - specifies that the file should consist of only exclude patterns, with no other rule-parsing
except for in-file comments.

o A + specifies that the file should consist of only include patterns, with no other rule-parsing
except for in-file comments.

o A C is a way to specify that the file should be read in a CVS-compatible manner. This turns on
’n’, ’w’, and ’-’, but also allows the list-clearing token (!) to be specified. If no filename is
provided, ".cvsignore" is assumed.

o A e will exclude the merge-file name from the transfer; e.g. "dir-merge,e .rules" is like
"dir-merge .rules" and "- .rules".

o An n specifies that the rules are not inherited by subdirectories.

o A w specifies that the rules are word-split on whitespace instead of the normal line-splitting.
This also turns off comments. Note: the space that separates the prefix from the rule is treated
specially, so "- foo + bar" is parsed as two rules (assuming that prefix-parsing wasn’t also dis‐
abled).

o You may also specify any of the modifiers for the "+" or "-" rules (above) in order to have the
rules that are read in from the file default to having that modifier set (except for the ! modi‐
fier, which would not be useful). For instance, "merge,-/ .excl" would treat the contents of .excl
as absolute-path excludes, while "dir-merge,s .filt" and ":sC" would each make all their per-direc‐
tory rules apply only on the sending side. If the merge rule specifies sides to affect (via the s
or r modifier or both), then the rules in the file must not specify sides (via a modifier or a rule
prefix such as hide).

Per-directory rules are inherited in all subdirectories of the directory where the merge-file was found
unless the ’n’ modifier was used. Each subdirectory’s rules are prefixed to the inherited per-directory
rules from its parents, which gives the newest rules a higher priority than the inherited rules. The
entire set of dir-merge rules are grouped together in the spot where the merge-file was specified, so it
is possible to override dir-merge rules via a rule that got specified earlier in the list of global rules.
When the list-clearing rule ("!") is read from a per-directory file, it only clears the inherited rules
for the current merge file.

Another way to prevent a single rule from a dir-merge file from being inherited is to anchor it with a
leading slash. Anchored rules in a per-directory merge-file are relative to the merge-file’s directory,
so a pattern "/foo" would only match the file "foo" in the directory where the dir-merge filter file was
found.

Here’s an example filter file which you’d specify via --filter=". file":

merge /home/user/.global-filter
- *.gz
dir-merge .rules
+ *.[ch]
- *.o

This will merge the contents of the /home/user/.global-filter file at the start of the list and also turns
the ".rules" filename into a per-directory filter file. All rules read in prior to the start of the
directory scan follow the global anchoring rules (i.e. a leading slash matches at the root of the trans‐
fer).

If a per-directory merge-file is specified with a path that is a parent directory of the first transfer
directory, rsync will scan all the parent dirs from that starting point to the transfer directory for the
indicated per-directory file. For instance, here is a common filter (see -F):

--filter=': /.rsync-filter'

That rule tells rsync to scan for the file .rsync-filter in all directories from the root down through the
parent directory of the transfer prior to the start of the normal directory scan of the file in the direc‐
tories that are sent as a part of the transfer. (Note: for an rsync daemon, the root is always the same
as the module’s "path".)

Some examples of this pre-scanning for per-directory files:

rsync -avF /src/path/ /dest/dir
rsync -av --filter=': ../../.rsync-filter' /src/path/ /dest/dir
rsync -av --filter=': .rsync-filter' /src/path/ /dest/dir

The first two commands above will look for ".rsync-filter" in "/" and "/src" before the normal scan begins
looking for the file in "/src/path" and its subdirectories. The last command avoids the parent-dir scan
and only looks for the ".rsync-filter" files in each directory that is a part of the transfer.

If you want to include the contents of a ".cvsignore" in your patterns, you should use the rule ":C",
which creates a dir-merge of the .cvsignore file, but parsed in a CVS-compatible manner. You can use this
to affect where the --cvs-exclude (-C) option’s inclusion of the per-directory .cvsignore file gets placed
into your rules by putting the ":C" wherever you like in your filter rules. Without this, rsync would add
the dir-merge rule for the .cvsignore file at the end of all your other rules (giving it a lower priority
than your command-line rules). For example:

cat <<EOT | rsync -avC --filter='. -' a/ b
+ foo.o
:C
- *.old
EOT
rsync -avC --include=foo.o -f :C --exclude='*.old' a/ b

Both of the above rsync commands are identical. Each one will merge all the per-directory .cvsignore
rules in the middle of the list rather than at the end. This allows their dir-specific rules to supersede
the rules that follow the :C instead of being subservient to all your rules. To affect the other CVS
exclude rules (i.e. the default list of exclusions, the contents of $HOME/.cvsignore, and the value of
$CVSIGNORE) you should omit the -C command-line option and instead insert a "-C" rule into your filter
rules; e.g. "--filter=-C".

LIST-CLEARING FILTER RULE
надоело копипастить
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Ленивая Бестолочь »

drBatty писал(а):
18.05.2012 07:17
перед написанием ерунды ознакомьтесь с man cp

да, чето я облажался :-)
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:
Аватара пользователя
Rassol2
Сообщения: 120

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

тут еше такой вопрос.
как запустить скрипт с заниженным приоритетом, с NICE?
Это нужно код дописать в скрипт ? Или это можно заложить в задачу cron, в мане по cron не нашел подобной вещи.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Решено: Копирование файлов с определенным расширением.

Сообщение drBatty »

Rassol2 писал(а):
22.05.2012 01:04
как запустить скрипт с заниженным приоритетом, с NICE?

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

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

Re: Решено: Копирование файлов с определенным расширением.

Сообщение Rassol2 »

а что эти знаки в конце команды обозначают
find \( -name "*.mp3" -o -name "*.mp4" -o -name "*.avi" \) -exec cp --parents -v -t target_dir/ {} +
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Решено: Копирование файлов с определенным расширением.

Сообщение sash-kan »

$ man find
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: Решено: Копирование файлов с определенным расширением.

Сообщение drBatty »

Rassol2 писал(а):
04.06.2012 11:44
а что эти знаки в конце команды обозначают

они меняются на имя файла. В данном случае на несколько имён файла. Т.е. если мы пишем

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

find -name '*.txt' -exec cat {} +

, то выполняется команда

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

cat ./1.txt ./2.txt ./3.txt

(если найдены файлы ./1.txt ./2.txt ./3.txt)

ЗЫЖ обычно многие пишут

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

find -name '*.txt' -exec cat {} \;

в этом случае выполняться три команды

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

cat ./1.txt
cat ./2.txt
cat ./3.txt

что в данном случае не играет никакой роли. слеш перед точкой с запятой тут нужен для того, что-бы последняя была обработана командой find как надо (иначе эта точка с запятой будет передана в shell, которая её и обработает. А по синтаксису find, команда как раз должна заканчиваться аргументом ';')

sash-kan писал(а):
04.06.2012 12:16
$ man find

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

       -exec command ;
              Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to the command  until
              an  argument consisting of `;' is encountered.  The string `{}' is replaced by the current file name being processed everywhere
              it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.  Both of these
              constructions  might  need  to be escaped (with a `\') or quoted to protect them from expansion by the shell.  See the EXAMPLES
              section for examples of the use of the -exec option.  The specified command is run once for each matched file.  The command  is
              executed  in  the starting directory.   There are unavoidable security problems surrounding use of the -exec action; you should
              use the -execdir option instead.

       -exec command {} +
              This variant of the -exec action runs the specified command on the selected files, but the command line is built  by  appending
              each selected file name at the end; the total number of invocations of the command will be much less than the number of matched
              files.  The command line is built in much the same way that xargs builds its command lines.   Only  one  instance  of  `{}'  is
              allowed within the command.  The command is executed in the starting directory.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Ответить