sok fájl átnevezése

Fórumok

Arra gondoltam hogy sed-del kéne, de nem tudom hogy tényleg az-e a jó. Mindenesetre átneveznék sok fájlt. awk, grep stb. for ciklus.

Ez a valami - 2016.ext

Erre a valamire - (2016).ext

Tulajdonképpen zárójelbe tenném az évszámokat. Talán valahol kimaradt a kötőjel, de az biztos hogy az évszám után rögtön a kiterjesztés van. Ami bármi lehet.
Van erre esetleg valami feature? Linuxos megoldás érdekelne.

Hozzászólások

Nem tudom fejből a szintaxist, de szerintem a find lesz a barátod. man find

vagy

Google: find rename multiple files

Bár nem világos, hogy hogyan szeretnéd átnevezni a fájlokat. Minden fájlnévben a kiterjesztés előtti rész egy évszám? A kiterjesztés meg akármi? Ez még kellhet: Google: Extract filename and extension bash

Hirtelen:

#!/bin/bash
for i in *
do
	ext=$(echo "$i" | grep -o \\\..*)
	bn=$(basename "$i" $ext)
	eleje=$(echo $bn | head -c -5)
	ev=$(echo $bn | tail -c 5)
	mv $i "$eleje($ev)$ext"
done

Debian - The "What?!" starts not!
http://nyizsa.blogspot.com

Szerkesztve: 2020. 01. 04., szo - 22:09

Én ilyen feladatokra a find + xargs + prename toolokat használom. Régebben perl-el együtt került fel, újabban külön csomagból telepíthető. Debian/Ubuntu alapú distribeknél "rename", Fedora/EPEL vonalon "prename" a csomag neve.

https://www.systutorials.com/docs/linux/man/1-prename/

A fent vázolt problémt valahogy így:

find /some/directory -type f -name '*.ext' -print0 | xargs -r0 prename 's/(.*?)(\d+)(\.ext)$/$1($2)$3/'

renameutilsban van egy qmv, amit -f do val hívva kapsz egy listát az lstől, amit akármilyen editorban megszerkeszthetsz, aztán hajrá, adhocra ez egész jó szokott lenni. De egyébként amit buga írt, find, aztán egy jól paraméterezett valami rename cucc

Egyébként ha egyszer kell az átnevezést elvégezni, akkor kilistázod a fájlneveket egy fájlba, és egy normális szövegszerkesztővel (regexp replace, column selection, stb...) megcsinálod a bash fájl, ami mindent átnevez. Ez kb 5 perc lehet.

Buga kollégára hallgathatsz.

De felmerült bennem a kérdés, hogy milyen fontos dolog miatt tesz valaki zárójelet egy filenévbe? Értem, hogy lehet, de későbbi kereséseknél, vagy regexp szerinti csoportos műveleteknél az ilyenekből van a hagos basszázás. :)

Én ha tudom kerülöm.

"A megoldásra kell koncentrálni nem a problémára."

Szóköz, zárójelek és hasonló dolgok _nem_ valók fájlnévbe, ez alapvetően igaz lehetne, de nem csak karakterek sorozataként lehet feldolgozni ezt az infót, igaz, ahhoz már valamilyen értelmesebb nyelvet kell választani, nem a shell-t és az ott elérhető toolokat. Amik egyébként (élükön a find nevű csodával) sokszor igencsak szuboptimálisan működnek.

Bár a find egészen optimális, sokkal gyorsabb, mint az XTW.

Rengeteg művelet elvégzésére egy pár soros C program elé kell forkolni, ami ugye 2 db indítandó program.

Persze a sed sem rossz, csak ügyelni kell, hogy fájlonként legalább négyszer legyen elindítva. ;)

Semmi baj a find-al. Xargs-szal igazi csoda :) Akkor kezd körülményessé válni, amikor a samba userek valami lázálomtól vezérelve elkezdenek a filenevekbe $, #, !, ? karakterektereket pakolni. Mindegyikkel találkoztam. :( Ilyenkor a szóköz, vagy a zárójel már kispálya. :)

Egyébként ha valami shellben 5percnél több, vagy túl bonyolult akkor vetem be a perl -t. És jelenleg próbálok python-t tanulni.

"A megoldásra kell koncentrálni nem a problémára."

százezre vagy épp milliós(!) darabszámú fájlt tartalmazó könyvtárban fájlnév minta és mtime alapján próbálj takarítani (rm). Az a find, ami adott Linux disztrón elérhető volt, az minden egyes fájlra(!) csinált két(!) stat/fstat hívást, ami az univerzális kivitel miatt oké, de adott feladatra erősen elmarad az optimálistól. A megoldás egyébként falk egyszerű volt: perl-ben könyvtár megnyit, a fájlneveken végigmenve mindet vizsgált a minta alapján, és amelyik illeszkedett rá, arra egy stat(), és ha az mtime is megfelelt az elvártnak, akkor unlink. Nagyon nem mindegy, hogy mondjuk 1M fájlból n darab kipucolásához 2M+n rendszerhívás kell, vagy 1+k+n, ahol k az illeszkedő névvel bíró fájlok száma...

 

Takarításnál sosem volt gond. Könyvtárban mtime 'oszt jónapot. Max annyi számít a névben hogy a vége például .log,  vagy .gz . Az én környezetemben...

Az a vicces, egyszeri quest, amikor keresel valamit, file-ok tartalmában, esetleg módosítani akarsz egy stringet egy másikra. Többezres lista, nyilván. Elsőre nem akarsz perl-t írni, hiszen egyetlen parancs bash-ban. Aztán megjelennek user torz elméjében fogant "vicces" file nevek.

És igen, itt már perl... ;) De egyszeri küldetésnél nem firtatom a find optimális voltát. Viszont ha autómatizálok valamit, ami 1, vagy 5 prcenként fut, ott már inkább gondolkodom, ha kell többet is mint amennyibe 8GB RAM kerül. :)

Szóval egyetértünk.

"A megoldásra kell koncentrálni nem a problémára."

Naugye!  Most, így békeidőben nézek egy gépet. Másodpercenként 1000 fork/exec és 10000 context switch fut rajta. Gondolom, a 2M stat olyan 1 másodperc lehet, de ha 200, akkor sem lényeges.

A mintát meg megmondhatod a find vagy egyéb cuccnak is, meg darabokra vághatod a feladatot is. Ilyen törölgetésre kifejlesztettem a m(ulti)rm programot. Mind a 15 sort én írtam C-ben, elengedett kézzel! :-D Kap egy listát, és visszaadja, hogy csinált-e valamit és mit is. Ebbe belefér a törlés, az ENOENT és az egyéb hiba.

Az istenkirálycsászár perl valószíűleg azért futott le, mert esetleg precízebben sikerült megírni a program valamelyik részét.

Az ilyen alkalmazást meg lelőni, kivégezni és kihallgatni! ;)

Elvileg igazad van, a find mégis esélytelenül lassan dolgozott, strace mutatta meg, hogy stat() fstat() minden fájlra _legalább_ egy-egy alkalommal, (ha a minták valamelyike illeszkedett, akkor ismét mindkettő...). A find még el sem jutott az exec()-ig, hogy töröljön, úgyhogy kapott egy ctrl-c-t, ugyanannyi idő alatt a Perl-es megoldás már készen volt a törléssel is... Ha nem a saját szememmel láttam volna, én is nehezen hinném el, de azóta óvatosabb vagyok a find és a nagyon sok fájl témakörben...

A Perl script azért futott le gyorsabban, mert egyrészt nem hívott fölöslegesen stat és fstat-ot, illetve a mintaillesztés része is vélhetően ügyesebb/jobb, mint amit a find használt. (RHEL5 volt a környezet, sok-sok évvel ezelőtt)

Már látszik is a hiba: find + exec

Erre mindig azt mondtam, hogy okos, aki a find összes opcióját tudja, csak nem hasznos. ;)

Miközben a sok stat a problémád, de a sok exec nem. Egy lehetséges megoldás:

find [pl.: *.gz, vagy semmi}][pl.: |awk pattern]|mrm

A find helyett jóbb az ls -f vagy ls -U. Az ls is csak dirt olvas és nem fog annyit statolni.

Ha figyelembe veszed azt a szabályt, hogy a nagy mennyiségű forrás előállítása a legköltségesebb, majd a következő (jól megfogalmazott) filter után már tökmindegy, akkor mindig gyors lesz a működés.

A kiírásig se jutott el értelmes idő alatt a find - exec meg "+" nem "\;" lezárással, ahogy illendő ment volna. (Volt más felhasználása is a motyónak (adott időszakban keletkezett, mintákra illeszkedő nevű fájlok törlése pl.), amit vagy find (stat/fstat mindenre az időadat miatt), vagy ls trükkösen kapcsolózva és a dátum/idő adatokra matekozva lehetett volna megoldani - Perl-ben egyszerűbb volt :-)

Igen, de ezt olvasva: kodi.wiki/view/Naming_video_files/Movies gondolkodtam el rajta. Viszont eddigi tapasztalataim azt mutatják, hogy úgy is jó ahogy most van.
Még csak most kezdtem a kodizást - hm. milyen érdekes szó.
Viszont nagyon bosszant a dolog hogy egy androidos tv box nem képes felcsatolni egy ext3-as fájlrendszert úgy, hogy a felhasználói programok is hozzáférhessenek.

Sokat olvastam erről, és azt szűrtem le, hogy a névterek, illetve maga a firmware elkészítése a kulcs. Nem mindegy hogy milyen paraméterekkel fogatják le a firmwaret.
Ergo sokat nem tehetek. Jelenleg meghekkeltem a routeremet, és feltettem rá egy padavant, melyben ott egy nfs szerver. 

De ha valakinek van jobb ötlete ne fojtsa magába. Egy rootolt kínai csodáról van szó. Libreeleec nem érhető el az RK3318-ra. 

Szerkesztve: 2020. 01. 06., h - 21:29

midnight commander

kijelölöd mindet, amit átneveznél (insert vagy * és minta)

rename

beírod a mintát, pl.

*- 2016.ext
*- (2016).ext

OK

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.