Рекурсивное переименование файлов linux

Рекурсивное переименование файлов

Имеется каталог со множеством подкаталогов, в каждом из которых находится файл «readme». Нужно переименовать каждый файл «readme» в «readme_old». Как это сделать простой командой на bash?

find -type f -name 'readme' -exec rename "readme" "readme_old" '<>' \; 

пример, как не осилить rename, но не подать вид

Ну не осилил… Только не я один. 🙂

find -type f -name 'readme' -execdir mv readme readme_old \; 

Попытался выпендрится — не получилось. Если ты не в курсе, дружок, не у всех gnu find.

Пример, как не осилить, что rename несколько, но пытаться показать, что что-то знаешь.

Сработало! Огромнейшее СПАСИБО!

Если ты не в курсе, дружок, не у всех gnu find.

У кого нет gnu find, у того нет и rename из util-linux

Попытался выпендрится — не получилось.

А что если я шизофреник, и у меня именно так? А? А? А?

У кого нет gnu find, у того нет и rename из util-linux

Ну так то да, теоретически множество gnu мощнее множества linux-ов. Но это не важно, ибо задача то решается в рамках posix совершенно тупо:

$ find -name "readme" -type f -exec mv "<>" "<>"_old \; 

vodz ★★★★★ ( 06.06.20 22:17:17 MSK )
Последнее исправление: vodz 06.06.20 22:18:53 MSK (всего исправлений: 1)

очень интересно содержимое этих readme, заинтриговал

Полезное добавление, спасибо.

Всё проще. readme это условное название. Требовалось только переименование одноимённых файлов.

ибо задача то решается … совершенно тупо

Думаешь, ТС осилит твой перл? Мой ответ соответствует его уровню понимания «простой команды», и он может осилить изменить его под свои нужды.

Читайте также:  Any desk для линукс

Изначально такой задачи не было. Эта надуманная проблема началась из-за «попытался выпендрится — не получилось». Я написал свой вариант без какой-либо (эмоциональной) оценки оппонента.

Никто никому здесь не соответствует.

Ответ на подобное всегда на ЛОРе был таким:

cat test. test. test. | perl -e .

Да успокойтесь вы… Вам же было сказано — «попытался выпендриться — не получилось». Что делает хороший человек, когда его просят помочь? Правильно, помогает. Что делает дебил недоучка, с неудовлетворёнными амбициями? Правильно -пытается показать, что он что то знает, но никому не скажет. Попросту выпендривается.

Чтобы не возникало вопросов, скажу «умникам» таки зачем мне это было нужно:

find -type f -name «.checksums» -exec rm -f <> ;

find -type f -name «.pkgfiles» -exec rm -f <> ;

find -type f -name ‘spkgbuild’ -execdir mv spkgbuild Pkgfile ;

find -type f -name Pkgfile -exec sed -i -r ‘s/#\ depends/#\ Depends\ on/g’ <> ;

Просто тупанул в одном месте и «сделал звонок товарищу». Всё, успокойтесь, любители делать гадости…

cdrw ( 07.06.20 15:01:33 MSK )
Последнее исправление: cdrw 07.06.20 15:13:42 MSK (всего исправлений: 2)

find -type f -name ‘spkgbuild’ -execdir mv spkgbuild Pkgfile ;

vodz , твой простой posix-совместимый ответ на это

Любитель выдумывать? Про то, что для каждой задачи свой инструмент, не слышали?

Источник

Recursively rename files (change extension) in Linux

How do I rename all files in a directory, recursively, changing one file extension to another, for thousands of files in thousands of subfolders? I see a lot of commands that do almost what I want, but not quite.

find . -name "*.andnav" -exec rename .andnav .tile <> \; syntax error at (eval 1) line 1, near "." 
rename -nv 's/\.andnav$/\.tile/i' *.andnav 0.png.andnav renamed as 0.png.tile 

7 Answers 7

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' <> \; ./0/0.png.andnav renamed as ./0/0.png.tile ./0/1.png.andnav renamed as ./0/1.png.tile ./1/0.png.andnav renamed as ./1/0.png.tile ./1/1.png.andnav renamed as ./1/1.png.tile 

of course remove the -v when actually doing it, or it will waste time displaying all the files

autoload zmv zmv -n '(**/)(*).andnav' '$1$2.tile' 

Remove the -n to actually perform the renaming.

find . -name '*.andnav' -exec sh -c 'mv "$0" "$.tile"' <> \; 

Explanation

The above starts walking the directory tree starting at the current working directory ( . ). Every time a file name matches the pattern *.andnav (e.g., foo.andnav ) the following command is executed:

Читайте также:  Compare two file in linux

Where $0 is foo.andnav and $.tile replaces the .andnav suffix with .tile so basically:

I just meant an explanation of the syntax and behaviour- people (like me!) might not be familiar with bash parameter expansion

I found this method is easier and easier to read:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/" 

At least on Ubuntu derivations rename takes a list of files from STDIN if none are on the command line. And this can be tested easily with:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/" 

find -execdir rename

https://superuser.com/a/213146/128124 works directly only for suffixes, but this will work for arbitrary regex replacements on basenames:

PATH=/usr/bin find . -depth -execdir rename 's/_dbg.txt$/_.txt' '<>' \; 
PATH=/usr/bin find . -type f -execdir rename 's/_dbg.txt$/_.txt' '<>' \; 

-execdir first cd s into the directory before executing only on the basename.

Tested on Ubuntu 20.04, find 4.7.0, rename 1.10.

Convenient and safer helper for it

find-rename-regex() ( set -eu find_and_replace="$1" PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \ find . -depth -execdir rename "$" "s/$" '<>' \; ) 

Sample usage to replace spaces ‘ ‘ with hyphens ‘-‘.

Dry run that shows what would be renamed to what without actually doing it:

Command explanation

The awesome -execdir option does a cd into the directory before executing the rename command, unlike -exec .

-depth ensure that the renaming happens first on children, and then on parents, to prevent potential problems with missing parent directories.

-execdir is required because rename does not play well with non-basename input paths, e.g. the following fails:

rename 's/findme/replaceme/g' acc/acc 

The PATH hacking is required because -execdir has one very annoying drawback: find is extremely opinionated and refuses to do anything with -execdir if you have any relative paths in your PATH environment variable, e.g. ./node_modules/.bin , failing with:

find: The relative path ‘./node_modules/.bin’ is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH

-execdir is a GNU find extension to POSIX. rename is Perl based and comes from the rename package.

Читайте также:  Dhcp linux red hat

Rename lookahead workaround

If your input paths don’t come from find , or if you’ve had enough of the relative path annoyance, we can use some Perl lookahead to safely rename directories as in:

git ls-files | sort -r | xargs rename 's/findme(. *\/)\/?$/replaceme/g' '<>' 

I haven’t found a convenient analogue for -execdir with xargs : Xargs: change working directory to file path before executing?

The sort -r is required to ensure that files come after their respective directories, since longer paths come after shorter ones with the same prefix.

Источник

Оцените статью
Adblock
detector