Hozzászólások
Egy scriptben szeretném feldolgoztatni egy könyvtár összes állományát. Ehhez kellene valami, ami készít egy teljes (rekurzív) listát a könyvtár fájljairól az abszolút úttal együtt. Persze az 'ls -aR' tűnik a legkézenfekvőbbnek, de ez nem produkál olyan kimenetet, amit egyszerűen fel lehetne dolgozni:
[code:1:facae4aca6]./.evolution:
. addressbook calendar cert8.db mail tasks
.. cache camel-cert.db key3.db secmod.db
./.evolution/addressbook:
. .. local
./.evolution/addressbook/local:
. .. system
./.evolution/addressbook/local/system:
. .. addressbook.db addressbook.db.summary
./.evolution/cache:
. ..
./.evolution/calendar:
. .. config local
[/code:1:facae4aca6]
- A hozzászóláshoz be kell jelentkezni
[quote:db2da92804="norcrys"]Ehhez kellene valami, ami készít egy teljes (rekurzív) listát a könyvtár fájljairól az abszolút úttal együtt.
find
- A hozzászóláshoz be kell jelentkezni
Első blikkre ez:
[code:1:629e7208fd]
find . -exec rm {} \;
[/code:1:629e7208fd]
vagy
[code:1:629e7208fd]find . > filelista.txt[/code:1:629e7208fd]
- A hozzászóláshoz be kell jelentkezni
Na, ez egyszerűbb, mint gondoltam. Féltem, hogy túl triviális lesz, de bonyolult scriptet simán megírtam, a find meg nem jutott eszembe. :oops:
- A hozzászóláshoz be kell jelentkezni
for list in *; do echo $list; done
...és akkor külső programot sem kell meghívni. :wink:
- A hozzászóláshoz be kell jelentkezni
[quote:2362cd0c97="hunger"]for list in *; do echo $list; done
...és akkor külső programot sem kell meghívni. :wink:
Ez szuper. Erre sem gondoltam, végig az ls kimenete bosszantott. :evil:
- A hozzászóláshoz be kell jelentkezni
cd /
du -a
- A hozzászóláshoz be kell jelentkezni
Jah, közben leesett, hogy rekurzívan kellene végigmenni az alkönyvtárokon is. Persze akkor sem olyan nagy ügy.
Első körben én valami ilyesmire gondoltam:
rekurzio() { for list in *; do if test -d "$list"; then cd "$list"; rekurzio; cd ..; else echo $list; fi; done; }; rekurzio;
Nem teljesen tökéletes, mert a kötőjellel kezdődő könyvtárneveket és egyéb érdekességeket nem kezeli le rendesen, de kiindulásnak szerintem megfelelő.
- A hozzászóláshoz be kell jelentkezni
[quote:37848232f1="hunger"]Jah, közben leesett, hogy rekurzívan kellene végigmenni az alkönyvtárokon is. Persze akkor sem olyan nagy ügy.
Első körben én valami ilyesmire gondoltam:
rekurzio() { for list in *; do if test -d "$list"; then cd "$list"; rekurzio; cd ..; else echo $list; fi; done; }; rekurzio;
Nem teljesen tökéletes, mert a kötőjellel kezdődő könyvtárneveket és egyéb érdekességeket nem kezeli le rendesen, de kiindulásnak szerintem megfelelő.
Ezzel csak az a baj, hogy a "cd" miatt relatív fájlneveket ír*, valamint sokkal lassabb a find-nál**, de az ötlet jó :)
Meg utálom a rekurziót, múltkor is memória hibát követett el egy rekurzív függvényem, pedig nem hagytam túlcsordulni.
*igaz, ezt lehet orvosolni
**ez meg csak kötözködés
- A hozzászóláshoz be kell jelentkezni
A 'for i in *;'-gal csak óvatosan, mert ugye a csillagot shell bontja ki, és pár tízezer file esetén simán feladja az osztályharcot, hasonlóan az 'rm *' is megmakkan tőle, csak itt nem a lista, hanem a parancssor lesz túl hosszú. Eddigi tapasztalataim szerint a 'find . -type f -exec rm {} \;' a leghatékonyabb, bár kicsit időigényes, hogy a file-okra egyesével indítgatja az rm-et.
- A hozzászóláshoz be kell jelentkezni
[quote:bec47a5a42="gsimon"]find . -type f -exec rm {} \;
Ennél sokkal jobb:
find . -type f | xargs rm
illetve az abszolút atombiztos változat ami helyesen kezel minden extrém fájlnevet:
find . -type f -print0 | xargs -0 -r rm --
Az xargs lényege, hogy egy rm parancsra annyi fájlt rábíz, amilyen hosszú csak lehet a parancssor, tehát megtalálja az arany középutat a fájlonként külön processz és a túl hosszú argumentumlista miatti elhasalás között.
- A hozzászóláshoz be kell jelentkezni
[quote:526c5e670e="egmont"]
illetve az abszolút atombiztos változat ami helyesen kezel minden extrém fájlnevet:
find . -type f -print0 | xargs -0 -r rm --
ezt koszi, eddig meg nem dobbentem ra, hogy a -print0 milyen hasznos a find-ben:)
- A hozzászóláshoz be kell jelentkezni
Na, ez a perl kód meghozta a kódolási kedvemet is. Akkor legyen itt a működő python kód (eddig még nem szállt el). Ez is nagyon egyszerű.
[code:1:06a0277eef]#!/usr/bin/python
import sys, os, os.path
def rekurziv_filecseszegeto(directory):
filenames = os.listdir(directory)
dirname = os.path.dirname(directory)
for filename in filenames:
fname = dirname + "/" + filename
if os.path.isdir(fname):
rekurziv_filecseszegeto(fname + "/")
// ..... feldolgozás...
rekurziv_filecseszegeto(sys.argv[1])
[/code:1:06a0277eef]
Ja, és mennyivel áttekinthetőbb, mint a perl... Na, ezért is szeressük a (Monthy) Pythont. 8)
- A hozzászóláshoz be kell jelentkezni
Ehe, ez hihetetlen :)
Ma este szivtam a dologgal, meg is csináltam a magam módján, pedig elég lett volna ezt a fórumot felkeresni :)
Az én megoldásom:
[code:1:d635db9c5f]ls -R "/mnt" | awk \
'{if($0~/.+/)
{if($0~/^\/mnt/) {d=substr($0,0, length($0)-1)"/";}
else {print d$0} } }'
[/code:1:d635db9c5f]
- A hozzászóláshoz be kell jelentkezni
[quote:e7c9338d63="egmont"][quote:e7c9338d63="gsimon"]find . -type f -exec rm {} \;
Ennél sokkal jobb:
find . -type f | xargs rm
illetve az abszolút atombiztos változat ami helyesen kezel minden extrém fájlnevet:
find . -type f -print0 | xargs -0 -r rm --
Az xargs lényege, hogy egy rm parancsra annyi fájlt rábíz, amilyen hosszú csak lehet a parancssor, tehát megtalálja az arany középutat a fájlonként külön processz és a túl hosszú argumentumlista miatti elhasalás között.
Az első változat felejtendő. Egy rendes, UTF-8 kódolású könyvtárszerkezetre is sír már, hogy idétlen a fájlnév. A másodikat nem próbáltam.
- A hozzászóláshoz be kell jelentkezni
csak hogy a ruby se maradjon ki...
(megj.: a listázandó könyvtár nevét az első paraméteren kell átadni, pl "./prog /usr/local/", alapból a /tmp-t listázza)
(megj2.: futtatáshoz miután chmod +x -elve lett, pipeold be mondjuk egy xargs-ba és a xargs után jöhet a parancs neve amelyiket végre akarod hajtani mindegyik fileon)
[code:1:81562bd1c1]
#!/usr/bin/ruby
require 'find'
rdir = ARGV[0] || "/tmp"
Find.find(rdir) do |path|
if FileTest.directory?(path)
next
else
puts path
end
end
[/code:1:81562bd1c1]
- A hozzászóláshoz be kell jelentkezni
[quote:73c40c69ce="egmont"][quote:73c40c69ce="gsimon"]find . -type f -exec rm {} \;
Ennél sokkal jobb:
find . -type f | xargs rm
illetve az abszolút atombiztos változat ami helyesen kezel minden extrém fájlnevet:
find . -type f -print0 | xargs -0 -r rm --
Az xargs lényege, hogy egy rm parancsra annyi fájlt rábíz, amilyen hosszú csak lehet a parancssor, tehát megtalálja az arany középutat a fájlonként külön processz és a túl hosszú argumentumlista miatti elhasalás között.
Na, nem is gondoltam, hogy ennyire tudjuk variálni a témát :)
Köszi, ezt ki is próbálom.
Amúgy eredetileg python kezelné le a témát, de nagy "létszámú", sok rekurzív hívást igénylő foldereknél előrejelezhetetlen módon memóriahibával elszáll.
- A hozzászóláshoz be kell jelentkezni
[quote:ecb1344a2f="norcrys"]
Na, nem is gondoltam, hogy ennyire tudjuk variálni a témát :)
Köszi, ezt ki is próbálom.
Amúgy eredetileg python kezelné le a témát, de nagy "létszámú", sok rekurzív hívást igénylő foldereknél előrejelezhetetlen módon memóriahibával elszáll.
na meg egy megoldas. nem python kell, hanem perl:)
[code:1:ecb1344a2f]
#!/usr/bin/perl
sub whichfiles {
local $fullname= "$File::Find::name";
$_=$fullname;
-f $fullname && !/jpg$/ && do {
local $res = normalizer("", $fullname);
if ("$fullname" ne "$res") {
# print "$fullname\t=>\t$res\n" ;
rename($fullname,$res);
}
}
}
find(\&whichfiles, "$ARGV[0]" );
[/code:1:ecb1344a2f]
ARGV[0]-ban konyvtarnevet var teljes path-al, ha file, es nem jpg-re vegzodik, akkor dolgozik:)
Az esetek donto tobbsegeben joval gyorsabb, mint a shell-es find
- A hozzászóláshoz be kell jelentkezni