Változó fájlnevek átnevezése [Megoldva]

Sziasztok!

Arra lenne szükségem, hogy automatikusan időponttal létrehozott fájlokat:

valami (2022-01-02-12-10-20-10).txt

valami2 (2022-01-02-13-12-10-00).txt

átnevezzek a zárójelben lévő időbélyeg nélkül úgy, hogy ha van ilyen nevű fájl, akkor azt felül is írja és a végeredmény ez legyen:

valami.txt

valami2.txt

 

Köszi! 

Hozzászólások

Szerkesztve: 2022. 07. 18., h – 23:29

Valami ilyesmi? (Tudom, sokkal szebben is megoldható, de gyorsban ez sikerült :) "GNU bash, version 4.4.12(3)-release"-t használva működik... )

cat "$(ls -1 valami\ *.txt | sort -n | head -1 )" > valami.txt && rm "$(ls -1 valami\ *.txt | sort -n | head -1)"

x=2
for i in $(ls -1 valami\ *.txt | sort -n | tr " " "_" )
do
  cat "${i/_/ }" > valami${x}.txt && rm "${i/_/ }"
  x=$((${x}+1))
done

Akkor valami ilyen (az egrep akkor kell, ha nagyon szigorúan adott formátumú fájlnevekre akarsz "lőni"):

 

n=$(ls -1 *\ \(*\).txt | egrep "\ \([0-9]{4}-([0-9]{2}-){5}[0-9]{2}\).txt" | sort -n | head -1 | tr " " "_" )"
cat "${n/_/ }" > $(echo $n | sed 's/_.*/.txt/') && rm "${n/_/ }

x=2
for i in $(ls -1 *\ \(*\).txt | egrep "\ \([0-9]{4}-([0-9]{2}-){5}[0-9]{2}\).txt" | sort -n | tr " " "_" )
do
  cat "${i/_/ }" > $(echo $i | sed 's/_.*/'${x}'.txt/' && rm "${i/_/ }"
  x=$((${x}++))
done

Te fűszernövény! :) Lényegében azt írtad, mintha x=$x; x=$((x+1)) lenne. Van benne most egy értékadás, ami önmagát adja értékül. Nem rossz, csak felesleges. Nem véletlenül írtam, hogy a Bash megengedi ezt a C-szerű formát: ((x++))

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szerkesztve: 2022. 07. 18., h – 23:31
Get-ChildItem -Path . | ForEach-Object {
    $Destination = $_.FullName -replace "(.*)\s+\([\d-]*\)(.txt)", "`$1`$2"
    if ($Destination -cne $_.FullName) {
        Move-Item -Path $_.FullName -Destination $Destination -Force
    }
}
Szerkesztve: 2022. 07. 19., k – 10:07

Pythonban:

import pathlib as pth

for fi in pth.Path(".").glob("* (*).txt"):

    newfn= fi.name.split(" (")[0] + ".txt"
    print( fi, "-->", newfn)
    fi.rename( newfn)

Talán így is lehetne:

#!/bin/sh

for i in *\(????-??-??-??-??-??-??\)*; do
    eval $(echo $i | sed s'/^\(.*\)\((....-..-..-..-..-..-..)\)\(.*\)$/A="\1" B="\2" C="\3"/')
    mv -- "$A$B$C" $(echo "$A$C" | tr -d ' ')
done
Szerkesztve: 2022. 07. 19., k – 12:26

A perl rename utilityjét pont ilyen feladatokra találták ki.

prename 's/(.*\S)\s*\(.*\)(\.\S+)$/$1$2/' *

Debian/Ubuntu szállítja csomagként (prename), Red Hat esetén EPEL-ben találod.

for i in *; do mv "$i" `echo "$i" | sed s/\ \(.*\)//`; done

A for i in * és a "${i}" miatt a szóköz kezelhető - egyébként meg jól benéztem, mert ha csak a szóköztől a timestamp végén lévő )-ig kell takarítani, akkor (fentebb megjelölt bash verzióval működik, a *\ *.txt minta perste simán "cifrázható" még):
 

for i in *\ *.txt ; do cat "$i" > "${i/ */.txt}" && rm "$i"; done

Az mv egy baromarc :) van neki -f kapcsolója, ami egyébként default (vagy nem...) - egyébként az indokolta a cat-ot, hogy lusta voltam a tesztfájlokat kézzel minden futás után újraalkotni - az rm csak a végén került bele, szóval valóban átgondolatlanul maradt így.

Szerintem ez a legelegánsabb megoldást. Én mondjuk inkább Vifm + vim-et használnék rá, Vifm-ben fájlokat kijelölöm, cw (átnevezés), megnyitja a fájlneveket (n)vim-ben, ott meg :%s/\ \(.*\)//. Ebben csak az a jó, ha nem lenne jó a mintailleszkedés, akkor csere után azonnal látom, és még nincsenek átnevezve a fájlok, elkapom időben, nyomok egy u-t (undo) a szerkesztő bufferben, és kezdem elölről, majd ha minden fájlnév jónak látszik csere után, ZZ-vel kilépek, és átnevezi a fájlokat. Kicsit körülményesebb, mint egy egysoros shell-megoldás, de biztonságosabb is az interaktivitás miatt. Nagyon könnyű félrefogalmazni egy regexpet, és onnantól oltári kín rosszul átnevezett fájlok nevét megpróbálni javítani. Tapasztalat.

Egyébként ha a kolléga hadilábon állna a regexp-pel, akkor ajánlom neki a Double Commandert. Ez grafikus GUI megoldás, de nagyon felhasználóbarát, van benne tömeges átnevezés, és mikor az ember írja be a mintát, már menet közben mutatja, hogy hogyan változnak majd a fájlnevek, meg folyamatos élő-súgót nyújt, hogy milyen mintailleszkedési sablonokat lehet bevinni (egy az egyben a Total Commanderből koppintották ezt a funkciót), így még olyan normik és Win Pistik is boldogulnak vele, akik képtelenek a regexpet meg a vim-et megtanulni. Ez a megoldás is biztonságos, mert élőben látod a változásokat előnézetben, és csak akkor nyomsz véglegesítést, ha tényleg jónak tűnik az összes fájlnév. Így nincs az, hogy félre lett fogalmazva meg félregépelve valami, és összeszarná az ember egy csomó fájl nevét.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Szerkesztve: 2022. 07. 21., cs – 08:26

Elnézést, de eddig nem volt időm megköszönni... Szóval elég akut volt a probléma és gyors megoldás kellett közel 8000 fájl átnevezésére. Születtek itt nagyon jó ötletek, de igazából addigra már megoldódott (mert meg kellett oldódnia 19. reggel 8-ra) a probléma, még ha nem is szépen :)

Egyébként ez lett:

find . -name "*2022-07-18*.txt" -type f | rename 's/ /_/g'
for j in `seq 7980`; do
    for i in $(find . -name "*2022-07-18*.txt" -type f | sort -n | head -1); do
        for k in $( find . -name "*2022-07-18*.txt" -type f | sort -n | head -1 | cut -d '_' -f1); do 
            mv $i $k.txt
        done
    done
done
 

Nem ez a legszebb megoldás, viszont működött...a többi ötlet meg a jövőben jó lesz :)
Még egyszer köszönöm!

üdv: pomm

A 852-es kídlap telepötúsa sikeresen befejezádétt

Egyszerhasználatos script esetében szerintem jók az ilyen megoldások. Írja az ember, ahogy eszébe jut, nem gondolkodik sokat, nem optimalizál, azért van a számítógép, hogy megoldja. Akkor kell optimalizálni, ha ebből rendszeres használatú segédeszköz lesz, vagy termék.

Mondjuk ilyen scriptet valóban télen illik futtatni. :D

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Az végül is nem olyan sok fájl, főleg ha SSD van a modern rendszer alatt, annyit secperc átnevez, általában olyan villám gyorsan, hogy a ventiknek nincs ideje felkapcsolni. Mármint Linux alatt. A Windows más téma, annál mindig nagyon szar a sok kis fájllal végzett műveletek teljesítménye.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Ja, hogy 3-4 perc. Ezen átsiklottam. Kicsit soknak tűnik az ~8k darab fájlra. Lehet HDD van alatta, vagy valami lassabb külső meghajtóról vagy hálózati meghajtóról ment. Azzal a sed-es egysoros megoldással, amire válaszoltam, azzal nem lett volna szabad SSD-n egy olyan 1-5 mp.-nél tovább tartani. De mindegy, így is meg van oldva, az a 3-4 perc is kibírható, meg még mindig sokkal gyorsabb, mint kézzel átnevezgetni. Az ilyen egyszeri megoldásoknál csak az a lényeg, hogy ha nem is a legelegánsabban, de meg van oldva, tovább lehet lépni, úgyse fog többet kelleni.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Aha. Most már figyelmesebben elolvastam a scriptet, és tényleg, elég sok "sort" parancs az, ami azért kár, mert sort nélkül is működött volna. A head -1-ről sem értem, hogy minek bele. Azt a $(find blabla) részt ki lehetett volna egy futás után menteni egy $fajlok stringbe, úgy jóval kevesebb find futott volna le.

Ennek ellenére az elvi megoldás érdekes, hogy cut-tal kivágta a szeparátor után az első mezőt. Az mehetett volna mindjárt cut -d ' ' -f1 segítségével, nem volt szükség erre a ' '-ről '_'-re történő köztes átnevezésre. A cut delimiternek megeszik bármilyen karaktert és stringet.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Ennek ellenére én javasolni szoktam, hogy legalább a POSIX (sed, grep, stb.) és Perl regexpet (ezt nem csak a Perl támogatja, hanem egy csomó másik szoftver is) mindenki tanulja meg. Igen, először pain in the ass megérteni, hieroglif krix-kraxnak tűnik. Sokan ágálnak is ellene, hogy ők nem tanulják meg, bonyolult, olvashatatlan, ők nem programozók, hanem hobbisták, userek, sysadminok, nekik nem kötelességük a kódolás. Valóban nem, de még normál userként is nagy hasznát venni, rendszeren előfordulnak ilyen tömeges átnevezések, meg több dokumentumban bizonyos előfordulások komplex cseréje, pl. nekem régi szótáranyagok konvertálásánál is nagyon jól jött sokszor, pedig én se vagyok coder, csak hobbista. Garantálom, hogy nem csak egyszer fog jól jönni, hanem rendszeresen életet ment.

Ugyanezen okból nem árt a shellt, vi/vim-et, coreutilokat stb. is minimum szinten megtanulni használni, nem kell ultrapro szint, nem kell szeretni, nem kell minden trükköt és kapcsolót, GNU vs. POSIX különbségeket ismerni, csak egy alap elboldogulás, man-olvasgatásos szinten érteni hozzá, azok is életet menthetnek, ha pl. egy szerveren nincs más fent, hirtelen kell visudo-zni (nincs idő EDITOR változót átállítgatni, nincs lehetőség másik text editort feltenni), stb.. Amit még javasolni szoktam, az a gépírás, otthon, egyéniben, ingyen megtanulható egy kis fegyelemmel és gyakorlással, és akkor is nagyon hasznos, ha az ember nem szegődik titkárnőnek, csak chatelésre, e-mailezésre, fórumozásra használja. Ezek mind olyan univerzális skillek, amik mindig használhatók maradnak, sose avulnak el.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

> hirtelen kell visudo-zni (nincs idő EDITOR változót átállítgatni,

Teljesen igazad van:

sudo -e lofasz.txt

helyett

env EDITOR=vi sudo -e lofasz.txt

az oly mértékű időkülönbség, hogy esélytelen (*). 14 plusz karakter! Szerintem azért kell megtanulni ezeket az alapparancsokat (pl. env), hogy ne mondjunk ilyen hülyeségeket. (Pl. szinte 100%, hogy nem visudo-ra gondoltál - azaz a sudoers szerkesztésre -, hanem sudo -e akármi.txt -re.)

Amúgy nagyjából egyetértek veled, de időnként a hátamon feláll a szőr attól amit írsz.

(*) Bourne-shell szintaxisú shellek esetén még az env szócska is elhagyható (bár így is működik), csh-szintaxisúak esetén viszont így muszáj írni.

Igen, azért írom, hogy lehet EDITOR változózni, de ne fogadj rá, nagyon sok olyan normi van, aki ilyen ubuntus tutorialok mentén gányol, és ők ezt vagy nem tudják, vagy nincs idő ezt a megoldást keresgetni, mert valamit azonnal, 0 határidővel kell működésre bírni. Csak egy példa volt, vannak még ilyenek, mikor a kényszer fura helyzeteket szül.

Én a sudo -e helyett sudoeditet használok, és de van doas és doasedit is fent. Általában az utóbbiakat veszem elő, de az első kettő csak ezért van fent, ha valami script vagy csomag fixre drótozva azokat akarná használni, akkor kompatibilis legyen a rendszer. Kicsit eltérően is használom, a doas-t általában akkor, ha valami spéci megoldásnál jelszó nélküli jogosultságemelést akarok beállítani egy scriptre, vagy hasonló, akkor ezt doas-ban könnyebb megtenni, mert jobb a conf fájljának a szintaxisa, emberközelibb, egyszerűbb, olvasható, mint a sudoers.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Szerkesztve: 2022. 07. 21., cs – 23:38

nemide.