Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: M Z 28. 07. 2022, 22:44:04
-
Zdravim,
resim takovy zapeklity problem. Mam v souboru seznam souboru ke smazani, jeden nazev souboru na radku a potreboval bych nejaky efektivni zpusob jak je smazat. Problemy jsou s tim dva. Jednak to muze byt vice nez milion souboru a take se v nazvech souboru bezne vyskytuji znaky jako "~{$', prakticky cokoliv co si dovedete predstavit. Zatim jsem neprisel na zadny zpusob jak v bash smazat soubor, ktery v nazvu obsahuje zaroven uvozovky a apostrofy >:(. Nefunguje ani finta:
tr '\n' '\0' < file | xargs -0 rm -f
Neslo by to napr. v Pythonu?
Diky
-
tr ... | while read ln ; do rm -f "$ln" ; done
nechodi?
-
sedama bych ten soubor promenil na bash skript, tj neco jako
cat seznam | sed "s/'/\'/g" | sed -r 's/(.*)/'"rm '\1'/" | bash
prvni escapne ' na \' a druhy to obali do rm 'radek' ... mozna jeste escapovat \ na \\ by to chtelo?
cat seznam | sed -r "s/['\\]/\\1/g" | sed -r 's/(.*)/'"rm '\1'/" | bash
(za spravny pocet zpetnych lomitek nerucim.. nezkousel jsem to - ale kdyz vypustis bash na konci tak si to muzes ulozit jako remove.sh a podivat se zda se to vse spravne escaplo)
-
Nejspíš se rm některé názvy jeví jako přepínače a mělo by stačit přídat --. A uniká mi důvod použití tr.
xargs -d '\n' rm -f -- <file
-
Taky se da mazat pres inode number, kdyz to jinak nejde.
Nebo pomocí *, kdyz zjistis zákonitosti názvů.
-
Asi bych si ten soubor nebo jeho vzorek setridil, analyzoval a pak v něm escapoval ty nevhodne znaky pomoci sed. Jestli ten escape nejde, tak mi neco asi uniklo.
Nedelal bych to jednou pipe i s remove, napred bych urcite konvertoval ten soubor, klidne na vic pruchodu.
Pred remove bych udelal urcite kontrolni ls, hlavne jestli jsou v tech adresarich i soubory ktere chces zachovat :-).
-
Zdravim,
resim takovy zapeklity problem. Mam v souboru seznam souboru ke smazani, jeden nazev souboru na radku a potreboval bych nejaky efektivni zpusob jak je smazat. Problemy jsou s tim dva. Jednak to muze byt vice nez milion souboru a take se v nazvech souboru bezne vyskytuji znaky jako "~{$', prakticky cokoliv co si dovedete predstavit. Zatim jsem neprisel na zadny zpusob jak v bash smazat soubor, ktery v nazvu obsahuje zaroven uvozovky a apostrofy >:(. Nefunguje ani finta:
tr '\n' '\0' < file | xargs -0 rm -f
Neslo by to napr. v Pythonu?
Diky
Jen pro zajimavost: jak jsi ten soubor se jmeny vytvoril ?
-
Taky to můžeš napsat v něčem co není shell a volat přímo příslušnou funkci jazyka, které se předává jméno a ona už s tím nedělá žádné operace. Třeba v Pythonu: for l in open("soubor").realines: os.remove(l[:-1])
-
smaž přes inode.
ls -il, v první sloupci máš inode id, pak smaž přes rm -i <inode>
-
smaž přes inode.
ls -il, v první sloupci máš inode id, pak smaž přes rm -i <inode>
To jsem taky navrhoval, ale má to jeden háček: musel by získat jména souborů znovu třeba ls -li * výpisem adresáře. Pokud by jako vstup pro ls -li použil ten zmiňovaný soubor, narazí na nachlup stejný problém jako s rm. Proto čekám až napíše jak ten soubor získal.
Nejlíp se mi líbí to Jendovo řešení, ale python neznám, tak nemuzu posoudit funkčnost.
-
Dekuji za vsechny odpovedi, vezmu to postupne:
Cokoli s while read ln je zoufale pomale a navic potom ani nefungu rm -f "$ln", protoze jmeno souboru muze obsahovat uvozovky
xargs -d '\n' rm -f -- <file -- Jo tohle funguje na 100%, finta s -- zabrala :D
Smazat pomoci inode by to slo, ale zjistit nejakym skriptem inode pro milion souboru bude trvat vecnost
Escapovat vsechny "nevhodne znaky" je prakticky nemozne, navic zase problem s miliony souboru
Je to export z GPFS metadat.
Takze dekuji Mr. tecka za fintu s "--", to me fakt nenapadlo.
-
Něco poobného jsem řešil (jen velkém množství, ne nutně divné znaky), ale začátek bylo find.
find má volbu -delete 8) (ale dát ji až na konec!)
-exec rm {} ;
-exec rm {} + (argumenty v jednom příkazu rm : rm f1 f2 f3 .... f4099)
Druhý - překročení délky commandline
První - zajímalo by mě ,jestli je to nějak optimalizované. Jestli i v přípdě, že bash nebude spoustět 5000 procesů (busybox styl) to nebude pomalé
Nakonec to vyřešil ten -delete.
-
Dekuji za vsechny odpovedi, vezmu to postupne:
Cokoli s while read ln je zoufale pomale a navic potom ani nefungu rm -f "$ln", protoze jmeno souboru muze obsahovat uvozovky
xargs -d '\n' rm -f -- <file -- Jo tohle funguje na 100%, finta s -- zabrala :D
Smazat pomoci inode by to slo, ale zjistit nejakym skriptem inode pro milion souboru bude trvat vecnost
Escapovat vsechny "nevhodne znaky" je prakticky nemozne, navic zase problem s miliony souboru
Je to export z GPFS metadat.
Takze dekuji Mr. tecka za fintu s "--", to me fakt nenapadlo.
Super. A nenarazis u xargs na prilis dlouhou delku command line ?
-
Chtěl jsem to ještě doplnit, na co jsem narazil a psal jsem to ,ale nedokončil řešení : xargs - N -n -l -L (něco z toho), liší se to args per line, možná to umí i paralelizaci
-
Cokoli s while read ln je zoufale pomale a navic potom ani nefungu rm -f "$ln", protoze jmeno souboru muze obsahovat uvozovky
WTF, `příkaz "$proměnná"` samozřejmě normálně předá příkazu parametr z proměnné (doslova ho to spustí a jako argv[1] bude mít obsah proměnné) a jestli v té proměnné je něco s uvozovkama nikdo neřeší.
-
Cokoli s while read ln je zoufale pomale a navic potom ani nefungu rm -f "$ln", protoze jmeno souboru muze obsahovat uvozovky
WTF, `příkaz "$proměnná"` samozřejmě normálně předá příkazu parametr z proměnné (doslova ho to spustí a jako argv[1] bude mít obsah proměnné) a jestli v té proměnné je něco s uvozovkama nikdo neřeší.
Problem neni v rm, ale v read.
Kdyz toho nechces tolik resit, tak musis delat neco jako
while IFS= read -r ln; do neco "$ln"; done
a ani to nefunguje dobre - jmena souboru dovoluji newline, kde se to rozbije na readu.
-
Problém byl v tom rm, kde je potřeba přidat --, které řekne, že tady končí přepínače a zbytek jsou názvy souborů.
Tím je problém vyřešený, tak přestaňte psát nesmysly, které nic neřeší a jen přidělávají další problémy. Akorát se ztrapňujete.
-
Problém byl v tom rm, kde je potřeba přidat --, které řekne, že tady končí přepínače a zbytek jsou názvy souborů.
Tím je problém vyřešený, tak přestaňte psát nesmysly, které nic neřeší a jen přidělávají další problémy. Akorát se ztrapňujete.
Ano, tati!