Как изменить расширения файлов в каталоге

У меня есть много файлов в каталоге, имеющих расширение.

.text(2)
.text(1)

Я хочу удалить номера из расширения и вывод должен быть как

.text 
.text

Может кто-нибудь, пожалуйста, помогите мне с сценарием оболочки для этого? Я использую CentOs 6.3.

4 ответа

Запустите однострочник в папке, в которой сохранены файлы, или измените путь для find команда. В следующих примерах find . путь . (Точка).

Тест с:

find . -type f -print0 | xargs -I{} -0 rename -v -n  's/\([0-9]+\)$//' {}

Переименовать с помощью:

find . -type f -print0 | xargs -I{} -0 rename -v  's/\([0-9]+\)$//' {}

Команда находит все файлы рекурсивно и удаляет все вхождения (<any_number>) в конце имени файла.

Удалить $ в 's/\([0-9]+\)$//' удалить все вхождения где-нибудь в имени файла, например:

find . -type f -print0 | xargs -I{} -0 rename -v  's/\([0-9]+\)//' {}

Пример:

% ls -oga
-rw-rw-r--  1 0 Jun 10 09:34 .foo(1)
-rw-rw-r--  1  0 Jun 10 09:34 .bar(2)
% find . -type f -print0 | xargs -I{} -0 rename -v  's/\([0-9]+\)$//' {}
% ls -aog
-rw-rw-r--  1    0 Jun 10 09:34 .foo
-rw-rw-r--  1    0 Jun 10 09:34 .bar

С помощью python:

#!/usr/bin/env python2
import os, re
for root, dirs, files in os.walk('/path/to/directory'):
    for f in files:
        oldname = os.path.join(root, f)
        newname = os.path.join(root, re.search(r'(?<=/)[^/]+(?=\(\d+\)$)', oldname).group())
        os.rename(oldname, newname)

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

  • os.walk будет проходить по всем подкаталогам в указанном каталоге

  • oldname будет содержать имя файла, который будет изменен. os.path.join добавит имя файла с путем к каталогу os.path.join

  • newname будет содержать название, что oldname будет изменено на. Здесь мы использовали re модуль, чтобы получить имя файла, а затем добавил имя файла к пути к каталогу с помощью os.path.join

  • os.rename просто переименует файлы соответственно.

До:

foo
├── 1 spam.text(1)
├── 1.text(23)
└── bar
    ├── 1 egg.text(10)
    └── 3test.text(5)

После:

foo
├── 1 spam.text
├── 1.text
└── bar
    ├── 1 egg.text
    └── 3test.text
for i in *.text*; do mv "$i" "$(echo "$i" | sed 's/([0-9]\{1,\})$//')"; done 

просто нужно изменить расширение (.text или любое другое расширение) в соответствии с необходимостью.

Это "дополнительный комментарий", а не полный ответ сам по себе.

Это действительно долгий способ "объяснить" второстепенную концепцию - он будет выглядеть длинным и педантичным, если только читатель не упустил из виду.

Краткое содержание:

Если существует более одного файла с именем, например foo.txt [(n)]

  • foo.txt, foo.txt(1) - переименовать - > без изменений
    Похоже, что ничего не произошло. Это сделал.

  • foo.txt(1), foo.txt(2) - переименовать -> foo.txt, foo.txt(2) (возможно)
    Один файл переименован, другой нет.


Longer:

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

Что касается системы

foo.txt = = foo.txt(1) = = foo.txt(2) = и т. д.

независимо от содержимого файла или размера.

т.е. если у вас есть два имени файла foo.txt с или без (n) после них, тогда система считает, что они дубликаты и / или дубликаты.
В любом случае процесс переименования не удастся.

Если в процессе переименования будут созданы два файла с одинаковыми именами, произойдет сбой при попытке создать 1-й дубликат. Но

В одном случае сбой не приведет к созданию какого-либо вывода, поэтому может показаться, что "ничего не произошло", когда произошло действительно "копирование не удалось из-за конфликта имен". Этот случай возникает, когда у одного файла нет суффикса (n), а у другого -.
например, если существуют файлы foo.txt и foo.txt(1), то переименование foo.txt(1) создаст дубликат, если это разрешено, поэтому не будет происходить, и никаких действий не будет.
foo.txt, foo.txt(1) - > без изменений

Но если к существующим файлам относятся, например, foo.txt(1) и foo.txt (2), то переименование foo.txt(1) НЕ создаст дубликат, поэтому произойдет, НО переименование foo.txt (2) впоследствии приведет к созданию дубликат, если это разрешено, поэтому никаких действий по переименованию второго файла не будет.
foo.txt(1), foo.txt(2) -> foo.txt, foo.txt(2) (возможно)

Другие вопросы по тегам