Дублирование и переименование файлов с совпадающими именами, но разными расширениями в bash?

Вопрос или проблема

Есть ли какой-то простой способ дублировать файлы с расширениями .cpp и .h (или любые другие расширения) одновременно в bash, вместо:

cp foo.cpp bar.cpp
cp foo.h bar.h

Я не ищу ответы в виде shell-скриптов или сложный синтаксис find или что-то в этом духе; мне просто интересно, есть ли что-то, встроенное в bash, что делает это простым способом.

Есть ли какой-то простой способ дублировать файлы с расширениями .cpp и .h (или любые другие расширения) одновременно в bash ….

интересно, есть ли что-то встроенное в bash, что делает это просто.

И ответ на сам вопрос: нет.

Напишите оболочку скрипта, создайте функцию, это не доступно по умолчанию.

Хотя эта функциональность не предоставляется по умолчанию, вы можете написать функцию оболочки, которая сделает это за вас. Эта функция оболочки может быть не простой (в зависимости от вашего знакомства с shell-скриптингом), но когда у вас она будет, ей будет просто пользоваться.

dup () {
    local root="$1"; shift
    local name

    for name do
        echo cp -i -- "$name" "$root.${name#*.}"
    done
}

Эта функция dup принимает новое корневое имя (часть имени файла до первой точки, отделяющая “корневую” часть имени файла от “расширения”), и список существующих имен файлов. Затем она дублирует каждый файл в списке, заменяя старый корень новым.

Определение dup выше фактически ничего не копирует. Удалите echo, чтобы она выполнила действие.

Тестирование (с echo на месте):

$ ls -l
total 0
-rw-r--r-- 1 myself myself 0 Mar  8 09:15 foo.cpp
-rw-r--r-- 1 myself myself 0 Mar  8 09:15 foo.doc
-rw-r--r-- 1 myself myself 0 Mar  8 09:15 foo.h
-rw-r--r-- 1 myself myself 0 Mar  8 09:22 foo.tar.gz
$ dup bar foo.*
cp -i -- foo.cpp bar.cpp
cp -i -- foo.doc bar.doc
cp -i -- foo.h bar.h
cp -i -- foo.tar.gz bar.tar.gz

С небольшим дополнением, чтобы функция работала с полными путями:

dup () {
    local root="$1"; shift
    local dirpath filename pathname

    for pathname do
        dirpath=$(dirname "$pathname")
        filename=$(basename "$pathname")
        echo cp -i -- "$pathname" "$dirpath/$root.${filename#*.}"
    done
}

Тестирование:

$ dup bar ~/foo.*
cp -i -- /home/myself/foo.cpp /home/myself/bar.cpp
cp -i -- /home/myself/foo.doc /home/myself/bar.doc
cp -i -- /home/myself/foo.h /home/myself/bar.h
cp -i -- /home/myself/foo.tar.gz /home/myself/bar.tar.gz

В zsh вы можете сократить for циклы:

for e (h cpp) cp {foo,bar}.$e

Или с zmv (включается с autoload -Uz zmv):

zmv -C 'foo.(h|cpp)' 'bar.$1'

Или с zargs (включается с autoload -Uz zargs):

zargs -I@ h cpp -- cp {foo,bar}.@

Не намного короче в этом случае, чем:

cp foo.h bar.h; cp foo.cpp bar.cpp

Ответ или решение

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

Теория

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

Пример

Рассмотрим создание функции в Bash, которая будет копировать файлы, изменяя только корень имени, оставляя расширения неизменными. В этом примере мы воплотим такую логику, используя базовые команды оболочки, как echo, dirname, и basename.

Функция dup предполагает, что вы передаете новое "корневое" имя (все, что до первой точки в имени файла) и список существующих файлов:

dup () {
    local root="$1"; shift
    local dirpath filename pathname

    for pathname do
        dirpath=$(dirname "$pathname")
        filename=$(basename "$pathname")
        echo cp -i -- "$pathname" "$dirpath/$root.${filename#*.}"
    done
}

Применение

Пример использования: Если у вас есть набор файлов с префиксом foo, например foo.cpp, foo.h, и ваша задача — создать копии этих файлов с новым именем bar, рекомендуется использовать функцию таким образом:

dup bar foo.*

Показанное выше будет выводить команды, которые выполнят необходимые копии. Важно заметить, что вследствие вызова echo, команды сначала только отображаются. Для фактического выполнения скопирования вам потребуется удалить echo, оставив:

cp -i -- "$pathname" "$dirpath/$root.${filename#*.}"

Таким образом, функция станет выполнять реальное копирование.

Контекст

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

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

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

Оцените материал
Добавить комментарий

Капча загружается...