Linux find переименовать файлы

Лисаков и макромир

Данное сообщение не претендует на оригинальность, это просто очередной пример того, как можно переименовать много файлов с помощью командной строки в Linux, используя find , sed , xargs и mv .

Общий вид

  1. Вывести имена нужных файлов ( ls , echo или find ).
  2. Произвести замену каждого имени и вывести старое имя и новое имя ( sed ).
  3. Применить к каждой паре старое имя – новое имя команду mv ( xargs ).

На языке bash эти 3 команды могут выглядеть так:

Мы будем говорить о последнем варианте, поскольку find является очень мощной и гибкой утилитой для поиска файлов.

Пример №1

Простейший случай, необходимо произвести такую замену с большим количеством файлов:

Для экспериментов создадим директорию

Теперь в директории

/test/ должно появиться 5 пронумерованных файлов. Выведем эти файлы (точка после find означает, что поиск надо проводить в текущей директории; ключ -type f просит выводить только файлы).

Потоковый редактор sed в команде find | sed получает поток названий файлов от find. И с каждым названием файла он может делать какую-то операцию. Нас интересует замена, общий вид которой в sed выглядит так.

Общий вид команд в редакторе sed:

Если выполнить данные команды, то sed будет ждать ввода аргументов с клавиатуры. После каждого нажатия Enter sed выведет строку, заменив в ней ‘old’ на ‘new’, если ‘old’ будет присутствовать в введённой строке. Но обычно sed используется либо в связках типа find | sed , либо принимает в качестве аргумента имена файлов, чтобы произвести замены внутри файлов.

Заметьте, что вы сами можете выбирать разделитель — например, / , # или : (хотя можно использовать почти любой символ), комбинировать их нельзя. Буква ‘s’ — заменить (от англ. substitute); буква ‘g’ (от англ. global) в конце стоит для того, чтобы замена происходила во всей строке не только для первого вхождения, а столько раз, сколько там встретится «old». Когда в заменяемых выражениях встречаются слэши ( / или \ ), то каждую из них приходится предварять дополнительным обратным слэшем, тогда код слишком сильно напоминает частокол и удобнее использовать двоеточие или что-то другое в качестве разделителя.

Итак, посмотрим, что мы можем сделать двумя первыми шагами find | sed :

Отлично, нужные нам имена выведены. Но в третьем шаге утилите xargs нужны и старое, и новое имя файла, чтобы применить к ним команду mv . Поэтому модифицируем команду sed :

Знак «p;» (p — print), стоящий перед «s», просит sed выдавать не только результат, но и исходный материал. Теперь вывод будет такой:

То, что нужно. Переходим к третьему шагу.

xargs

Программа xargs работает с потоками данных. Утилита принимает один поток и может «распараллелить» его на несколько. Чтобы было лучше понятно, посмотрите простые примеры:

Для переименования файлов, очевидно, нам нужен ключик -n2 , тогда xargs разделит поток из старых и новых имён в две колонки.

Отлично. Осталось перед каждой парой вставить mv , и переименование произойдёт. Выполняем:

Вывода никакого не последует, но переименование произошло. Чтобы быть уверенным в результате, можно произвести проверку перед выполнением этой команды. Для этого надо добавить ключ -p к xargs . Тогда утилита будет показывать, что она сделала бы без ключа -p . Можно нажимать Enter и просматривать, что собирается сделать команда. Изменения применены не будут.

Если результаты устраивают, то нужно убрать ключ -p и повторить команду.

Пример №2

В директориях dir1/subdir1/ , dir1/subdir2/ ,… dir5/subdir5/ лежат файлы filename.txt. Нужно вытащить их оттуда, но уже с разными именами.

Читайте также:  Как понять 32 или 64 битная система windows

При необходимости создадим и очистим нашу экспериментальную директорию

/test/ и создадим там необходимую структуру файлов:

Итак, у нас получилось 25 файлов filename.txt в директориях dir1/subdir1/ , dir1/subdir2 ,… dir5/subdir5/ .

Выведем эти файлы. В этом случае -type f тоже сработал бы, но воспользуемся для разнообразия поиском по имени. Также используем звёздочку вместо точки, чтобы избавиться от ведущего ./ в выводе.

Попросим sed заменить все слэши на дефисы.

xargs

Убедившись, что всё произойдёт правильно, убираем ключ -p и повторяем команду.

Пример №3

В директории лежат файлы, пронумерованные от 0 до 1001. Если их выводить командой ls , они будут отсортированы по имени не так, как этого хотелось бы [1] . Добавим необходимое количество нулей в названия файлов.

При необходимости создаём тестовую директорию и/или чистим её и создаём наши 1001 файл:

Можно действовать так (не лучший вариант).

Первая команда всем файлам, начинающимся с одной цифры, добавит 3 нуля. Вторая команда всем файлам, начинающимся с двух цифр, добавит 2 нуля. Третья команда всем файлам, начинающимся с трёх цифр, добавит 1 ноль.

Здесь использованы регулярные выражения в sed . Разберём конструкцию

  • ^ означает, что нужно искать с начала имени
  • конструкция \(. \) позволяет заключённое в неё использовать как \1 в шаблоне замены
  • 752 означает три любые цифры подряд.
  • — — просто дефис.

    В принципе, с этим можно справиться командой ls -v (natural sorting: 10 будет выведено после 9, а не после единицы), но мы всё-таки для упражнения произведём переименование. ↩︎

    Источник

    Поиск в Linux с помощью команды find

    Утилита find представляет универсальный и функциональный способ для поиска в Linux. Данная статья является шпаргалкой с описанием и примерами ее использования.

    Общий синтаксис

    путь к корневому каталогу, откуда начинать поиск. Например, find /home/user — искать в соответствующем каталоге. Для текущего каталога нужно использовать точку «.».

    набор правил, по которым выполнять поиск.

    * по умолчанию, поиск рекурсивный. Для поиска в конкретном каталоге можно использовать опцию maxdepth.

    Описание опций

    Тип объекта поиска. Возможные варианты:

    • f — файл;
    • d — каталог;
    • l — ссылка;
    • p — pipe;
    • s — сокет.
    Опция Описание
    -name Поиск по имени.
    -iname Регистронезависимый поиск по имени.
    -type
    -size Размер объекта. Задается в блоках по 512 байт или просто в байтах (с символом «c»).
    -mtime Время изменения файла. Указывается в днях.
    -mmin Время изменения в минутах.
    -atime Время последнего обращения к объекту в днях.
    -amin Время последнего обращения в минутах.
    -ctime Последнее изменение владельца или прав на объект в днях.
    -cmin Последнее изменение владельца или прав в минутах.
    -user Поиск по владельцу.
    -group По группе.
    -perm С определенными правами доступа.
    -depth Поиск должен начаться не с корня, а с самого глубоко вложенного каталога.
    -maxdepth Максимальная глубина поиска по каталогам. -maxdepth 0 — поиск только в текущем каталоге. По умолчанию, поиск рекурсивный.
    -prune Исключение перечисленных каталогов.
    -mount Не переходить в другие файловые системы.
    -regex По имени с регулярным выражением.
    -regextype Тип регулярного выражения.
    -L или -follow Показывает содержимое символьных ссылок (симлинк).
    -empty Искать пустые каталоги.
    -delete Удалить найденное.
    -ls Вывод как ls -dgils
    -print Показать найденное.
    -print0 Путь к найденным объектам.
    -exec <> \; Выполнить команду над найденным.
    -ok Выдать запрос перед выполнением -exec.

    Также доступны логические операторы:

    Оператор Описание
    -a Логическое И. Объединяем несколько критериев поиска.
    -o Логическое ИЛИ. Позволяем команде find выполнить поиск на основе одного из критериев поиска.
    -not или ! Логическое НЕ. Инвертирует критерий поиска.

    Полный набор актуальных опций можно получить командой man find.

    Примеры использования find

    Поиск файла по имени

    1. Простой поиск по имени:

    find / -name «file.txt»

    * в данном примере будет выполнен поиск файла с именем file.txt по всей файловой системе, начинающейся с корня /.

    2. Поиск файла по части имени:

    * данной командой будет выполнен поиск всех папок или файлов в корневой директории /, заканчивающихся на .tmp

    3. Несколько условий.

    а) Логическое И. Например, файлы, которые начинаются на sess_ и заканчиваются на cd:

    find . -name «sess_*» -a -name «*cd»

    б) Логическое ИЛИ. Например, файлы, которые начинаются на sess_ или заканчиваются на cd:

    find . -name «sess_*» -o -name «*cd»

    в) Более компактный вид имеют регулярные выражения, например:

    find . -regex ‘.*/\(sess_.*cd\)’

    * где в первом поиске применяется выражение, аналогичное примеру а), а во втором — б).

    4. Найти все файлы, кроме .log:

    find . ! -name «*.log»

    * в данном примере мы воспользовались логическим оператором !.

    Поиск по дате

    1. Поиск файлов, которые менялись определенное количество дней назад:

    find . -type f -mtime +60

    * данная команда найдет файлы, которые менялись более 60 дней назад.

    2. Поиск файлов с помощью newer. Данная опция доступна с версии 4.3.3 (посмотреть можно командой find —version).

    а) дате изменения:

    find . -type f -newermt «2019-11-02 00:00»

    * покажет все файлы, которые менялись, начиная с 02.11.2019 00:00.

    find . -type f -newermt 2019-10-31 ! -newermt 2019-11-02

    * найдет все файлы, которые менялись в промежутке между 31.10.2019 и 01.11.2019 (включительно).

    б) дате обращения:

    find . -type f -newerat 2019-10-08

    * все файлы, к которым обращались с 08.10.2019.

    find . -type f -newerat 2019-10-01 ! -newerat 2019-11-01

    * все файлы, к которым обращались в октябре.

    в) дате создания:

    find . -type f -newerct 2019-09-07

    * все файлы, созданные с 07 сентября 2019 года.

    find . -type f -newerct 2019-09-07 ! -newerct «2019-09-09 07:50:00»

    * файлы, созданные с 07.09.2019 00:00:00 по 09.09.2019 07:50

    По типу

    Искать в текущей директории и всех ее подпапках только файлы:

    * f — искать только файлы.

    Поиск по правам доступа

    1. Ищем все справами на чтение и запись:

    find / -perm 0666

    2. Находим файлы, доступ к которым имеет только владелец:

    find / -perm 0600

    Поиск файла по содержимому

    find / -type f -exec grep -i -H «content» <> \;

    * в данном примере выполнен рекурсивный поиск всех файлов в директории / и выведен список тех, в которых содержится строка content.

    С сортировкой по дате модификации

    find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r

    * команда найдет все файлы в каталоге /data, добавит к имени дату модификации и отсортирует данные по имени. В итоге получаем, что файлы будут идти в порядке их изменения.

    Лимит на количество выводимых результатов

    Самый распространенный пример — вывести один файл, который последний раз был модифицирован. Берем пример с сортировкой и добавляем следующее:

    find /data -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | sort -r | head -n 1

    Поиск с действием (exec)

    1. Найти только файлы, которые начинаются на sess_ и удалить их:

    find . -name «sess_*» -type f -print -exec rm <> \;

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

    2. Переименовать найденные файлы:

    find . -name «sess_*» -type f -exec mv <> new_name \;

    find . -name «sess_*» -type f | xargs -I ‘<>‘ mv <> new_name

    3. Вывести на экран количество найденных файлов и папок, которые заканчиваются на .tmp:

    find . -name «*.tmp» | wc -l

    4. Изменить права:

    find /home/user/* -type d -exec chmod 2700 <> \;

    * в данном примере мы ищем все каталоги (type d) в директории /home/user и ставим для них права 2700.

    5. Передать найденные файлы конвееру (pipe):

    find /etc -name ‘*.conf’ -follow -type f -exec cat <> \; | grep ‘test’

    * в данном примере мы использовали find для поиска строки test в файлах, которые находятся в каталоге /etc, и название которых заканчивается на .conf. Для этого мы передали список найденных файлов команде grep, которая уже и выполнила поиск по содержимому данных файлов.

    6. Произвести замену в файлах с помощью команды sed:

    find /opt/project -type f -exec sed -i -e «s/test/production/g» <> \;

    * находим все файлы в каталоге /opt/project и меняем их содержимое с test на production.

    Чистка по расписанию

    Команду find удобно использовать для автоматического удаления устаревших файлов.

    Открываем на редактирование задания cron:

    0 0 * * * /bin/find /tmp -mtime +14 -exec rm <> \;

    * в данном примере мы удаляем все файлы и папки из каталога /tmp, которые старше 14 дней. Задание запускается каждый день в 00:00.
    * полный путь к исполняемому файлу find смотрим командой which find — в разных UNIX системах он может располагаться в разных местах.

    Источник

    Как получить команду find и rename для работы с подкаталогами?

    Возможный дубликат:
    Рекурсивные файлы и каталоги переименования

    У меня есть большой каталог музыкальных файлов, которые часто меняются, когда файлы и каталоги приходят и уходят. Мое предпочтение состоит в том, чтобы убедиться, что имена файлов и каталогов не содержат пробелов, поэтому я заменяю их символами подчеркивания.

    Я захожу в основной каталог и запускаю эту команду:

    Проблема в том, что когда есть подкаталоги, эта команда, кажется, теряется и возвращает ошибки. Поэтому, если у меня есть следующая структура каталогов:

    … и если я запустил команду, то получаю следующие ошибки:

    И тогда результат заключается в том, что моя структура каталогов выглядит так. Обратите внимание, что в подкаталогах по-прежнему есть пробелы:

    Если я снова запустил команду, я получу эти ошибки, хотя кажется, что, возможно, она переименовала указанные каталоги:

    Наконец, я запускаю команду еще один раз, и у меня нет ошибок, и у меня есть все каталоги и подкаталоги, названные так, как я хочу:

    Очевидно, что это требует выполнения команды еще больше раз, когда у меня есть несколько подкаталогов, которые могут стать утомительными.

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

    Моя конечная цель – включить это в сценарий Bash, чтобы я мог запускать его вместе с другими подобными командами, поэтому мне нужно, чтобы они не возвращали ошибки или не нуждались в большем количестве ввода от меня. Кроме того, я запускаю Ubuntu 12.04, если это имеет значение.

    Вот что происходит:

    • find находит соответствующий каталог ./Test 02 .
    • find выполняет команду rename в этом каталоге.
    • rename переименовывает Test 02 в Test_02 .
    • find пытается спуститься в каталог Test 02 . Но этого больше нет.

    Самый простой способ решить эту проблему – сказать, что find для работы наоборот: сначала найдите совпадения внутри каталога, а затем проверьте, совпадает ли сама директория. Это то, что -depth опция -depth .

    Если вы добавите только -depth , вы -depth другой проблемой, которая заключается в том, что при find достигает Test 01/Test A , он вызывает rename ‘y/\ /\_/’ ‘Test 01/Test A’ , который пытается переименуйте этот каталог в Test_01/Test_A . Это не сработает, поскольку нет директории с именем Test_01 . -execdir исправление заключается в использовании опции -execdir , которая вызывает rename внутри каталога Test 01 и передает Test A в качестве аргумента. Вы можете ускорить процесс, передав несколько аргументов для rename в одну партию, используя + вместо ; для завершения команды -execdir .

    Кроме того, используйте эту короткую, но загадочную команду zsh:

    Функция zmv переименовывает файлы в соответствии с шаблонами. Исходный шаблон – **/* , который соответствует всем файлам ( * ) во всех подкаталогах рекурсивно ( **/ ). Квалификаторы glob (активированные параметром -Q ) указывают, что только каталоги сопоставлены ( / ), и эти точечные файлы включены ( D ). Параметр -w создает обратную ссылку для каждого шаблона шаблона источника. Замена начинается с $1 которая обозначает совпадение для первого шаблона (для ** , это включает в себя final / ), за которым следует $ <2>, который равен $2 (что соответствует * совпадению) для замены все пробельные символы _ . Добавьте опцию -v чтобы увидеть, что делает команда, вы заметите, что она сначала пересекает глубину, как find -depth .

    Источник

    Читайте также:  Driver ikecfgif installation failed windows 10
Оцените статью