Portál AbcLinuxu, 7. května 2025 01:14
searchFolder="$1"
destinationFolder="$2"
if [ -d "$searchFolder" ] && [ -d "$destinationFolder" ] ; then
cd "$searchFolder"
for f in $(find $searchFolder -type f) ; do
echo -e " \e[31mProcessing: $f\e[39m"
if grep -q "KLICOVE SLOVO" "$f" ; then
echo -e "\e[32m Found: $f\e[39m"
echo "===========mv=============="
mkdir --parents "$(dirname "$destinationFolder${f/$searchFolder}")"
mv "$f" "$(dirname "$destinationFolder${f/$searchFolder}")"
fi
done
else
echo "Bad arguments"
fi
cd "$searchFolder" for f in $(find $searchFolder -type f) ; doTen mkdir by asi slo napsat jednoduseji:
mkdir --parents "$(dirname $destinationFolder/$f/$searchFolder)"Zase vystup $f u find je bez leading /, ale searchFolder muze byt s / nazacatku nebo bez a potom to bude problem. Takze toto nemusi uplne fungovat a to puvodni ma problem i u destinationFolder bez koncoveho /:
$destinationFolder/$f/$searchFolderPokud se nepletu tak tento grep bude fungovat na cely vystup find = celou cestu, ne jen na nazev souboru jako takovy, takze by to chtelo asi udelat jinak:
if grep -q "KLICOVE SLOVO" "$f" ; thenNo a konecne napriklad rsync by to cele mohl zvladnout s dobrym filtrem na jeden radek..
rsync --include [regexp] /A /B
cd
je tam zbytecne (pozustatek ze starsi verze), oba dva argumenty budou zadavany jako plna cesta, script se bude volat pres ssh z GUI rozhrani. Z toho duvodu nebude potreba resit osetreni uzivatelskych vstupu na serveru, kde script pobezi, to udela obsluzny program u klienta.
Nemuzu pouzit rsync
, protoze ten neumi soubory jen presunout (Kopirovani a nasledne mazani je nekolikanasobne pomalejsi). Pri presunuti je take potreba zachovat adresarovou strukturu.
Cilem je, aby byl script co nejrychlejsi (bude prochazet cca 10TB dat) a nemel problemy s diakritikou a nazvy souboru/slozek zacinajicich "--".
rg -wl 'slovo' .|parallel mkdir -p ../jine_umisteni/{//}\; mv -t ../jine_umisteni/{//} -- {}ale při 10TB to bude vždycky pomalé. Používá to
ripgrep
.
for f in $(find $searchFolder -type f) ; do ... donepoužít
find "$searchFolder" -type f -name "*.sh" -exec \ grep -l 'KLICOVE SLOVO' '{}' + | while read f; do echo -e "\e[32m Found: $f\e[39m" destination="$(dirname "$destinationFolder${f/$searchFolder}")" mkdir --parents "$destination" mv "$f" "$destination" done
searchFolder="$1" destinationFolder="$2" if [ -d "$searchFolder" ] && [ -d "$destinationFolder" ] ; then find "$searchFolder" -type f -exec \ grep -l 'KLICOVE SLOVO' '{}' + | while read f; do echo -e "\e[32m Found: $f\e[39m" destination="$(dirname "$destinationFolder${f/$searchFolder}")" mkdir --parents "$destination" mv "$f" "$destination" done else echo "Bad arguments" fiJen mi prijdou zvlastni ty uvozovky na radku 8:
destination="$(dirname "$destinationFolder${f/$searchFolder}")"
Neni potom v uvozovkach jen dirname
a zavorka na konci?
$(
přepíná kontext, takže dirname
v uvozovkách není, ale za příslušnou )
už zase je - proto se musí na konci uvozovkou uzavřít.
mkdirstdin(){ while read f; do mkdir --parents -- "$1${f%/*}"; printf "%s\n%s\n" "$f" "$1${f%/*}"; done; } find ./sourcedir -name "*.txt" -type f -exec grep -l 'najdivzor' {} \; | mkdirstdin /tmp/targetdir/ | xargs -P4 -L2 -d"\n" mv --a zdá se že je to rychlejší, než zde uváděný skriptík. S ripgrep jsem to neporovnával (nemám zatím nainstalovaný rust).
find, grep
za grep -r
.
[wamba@wamba-X220 Dokumentujo]$ time rg -uul 'slovo' | wc -l 19 real 0m0,162s user 0m0,254s sys 0m0,276s [wamba@wamba-X220 Dokumentujo]$ time find . -type f -exec grep -l 'slovo' {} \;|wc -l 19 real 0m55,467s user 0m37,120s sys 0m17,049s [wamba@wamba-X220 Dokumentujo]$ time grep -rl 'slovo' |wc -l 19 real 0m0,512s user 0m0,314s sys 0m0,196s
grep -r
je nepoužitelný, pokud nechceš prohledávat všechy soubory, např. chceš jen soubory s určitou příponou.
Také jsem si všiml, že jsi na konec příkazu find
nedal +
, ale \;
, což je řádově pomalejší.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.