Как изменить расширения файлов в каталоге
У меня есть много файлов в каталоге, имеющих расширение.
.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) (возможно)