#!/bin/bash
##################################################
# Fichier : s3f
# But : recherche de fichiers personalisée
# Détails : xav search-tool
# par analogie avec gst, gnome-search-tool
# nécessite zenity
# 20200716 : dossiers réseaux scannables par find, pas par updatedb (cf. find_network)
# 20180105 : S3F_HISTO (car découvert on peut lancer s3f depuis Alt-F2 sous Raspbian => on perd historique .bash_history)
# 20141117 : nouveau nom=s3f, super fast file finder
# 20120417 : nouveau nom=s, ancien nom=xst (xav search tool)
# 20111103 : TODO ajouter la possibilité de chercher du texte dans tous les fichiers texte des catalogues
# 20120308 : TODO mettre condition test existence fichier $i/.VIDE_NE_PAS_EFFACER_pour_xst
# pour éviter d'écraser l'index avec un index vide
# pastebin : http://pastebin.com/EkBVLdjf
# nécessite : sudo apt install locate # sur raspbian
####################fin_entete####################
##################################################
# TODO :
# - IMPORTANT : dossiers privés/publics
# - ne pas effacer un catalogue où media absent
#
SEARCHDIR=/media
# 1. constantes
verbose="FALSE"
afficher="FALSE"
EDITEUR=vim
# 2. variables par défaut
display_duration="FALSE"
lancerDIR="FALSE"
S3F_TMP=/tmp/s3f
S3F_HISTO=$0.histo
[ -d ${S3F_TMP} ] || mkdir ${S3F_TMP}
fResultats=$(mktemp ${S3F_TMP}/s3f_XXXXXXXX)
maxi_a_lancer=10
# variables à personnaliser
# dossier contenant les catalogues
DIR_CATALOGS=/home/pi/3en1/divers/mon_updatedb
# définir ici les dossiers à scanner
dossiers="$HOME" # 20200716 comprend nouveaux dossier cryptmount
dossiers="$dossiers;/media/pi/A-300GB"
dossiers="$dossiers;/media/pi/B-650GB"
find_network="/media/fbx"
#############################################################################
# TODO : ajouter décompta nb dossiers et fichiers par dossier de ${dossiers}
#############################################################################
# fonctions
on_cherche () {
# lister resultats
# (les enregistrer dans catalogues)
if [ $afficher = "TRUE" ] ; then
echo Arguments de recherche :
echo $*
fi
tmp1=$(mktemp ${S3F_TMP}/tmp1_XXXXXXXX) ; tmp2=$(mktemp ${S3F_TMP}/tmp2_XXXXXXXX)
x=$*
x="$@"
rm $fResultats 2>/dev/null
# 1. parcourir les catalogues et rechercher premier terme
# TODO : locate peut chercher en une passe
# dans tous les dossiers donnés en un seul paramètre (-d database1:database2:...)
set $x
for d in $(ls -1 ${DIR_CATALOGS} | grep ".updatedb" | grep -v lisezmoi.txt | grep -v "7z$")
do
echo LOCATE -d ${DIR_CATALOGS}/$d -i "$1"
locate -d ${DIR_CATALOGS}/$d -i "$1"
done > $tmp1
shift
# 2b. rechercher termes suivants
while [ ! "x$1" = "x" ]
do
grep -i "$1" $tmp1 >> $tmp2 # recherche insensible à la casse
mv $tmp2 $tmp1
shift
done
cat $tmp1 >> $fResultats
# 2. parcourir les catalogues réseau
set $x
for d in $(ls -1 ${DIR_CATALOGS} | grep ".find_network" | grep -v lisezmoi.txt | grep -v "7z$")
do
grep -i "$1" ${DIR_CATALOGS}/$d
done > $tmp1
shift
while [ ! "x$1" = "x" ] # 2b. rechercher termes suivants
do
echo GREP -i "$1" $tmp1 '>>' $tmp2 # recherche insensible à la casse
grep -i "$1" $tmp1 >> $tmp2 # recherche insensible à la casse
mv $tmp2 $tmp1
shift
done
cat $tmp1 >> $fResultats
rm $tmp1 $tmp2 2>/dev/null
#~ rm $fResultats
}
on_cherche_second_chance_OLD () {
zenity --info --title "En construction" --text "Aucun résultat. on_cherche_second_chance bientôt dispo (fuzzy search). Recherche sur des termes voisins à la google."
}
on_affiche_ou_lance_resultats () {
# lancer resultats
# $1 = LANCER => lancer première ligne
if [ "x$1" = "xLANCER" ] ; then
if [ $lancerDIR = "TRUE" ] ; then
echo "Lancement de la première ligne DOSSIER parent"
f="$(dirname $(head -1 $fResultats))"
nemo "$f"
else
echo "Lancement de la première ligne"
f="$(head -1 $fResultats)"
#~ xdg-open "$(head -1 $fResultats)"
nemo "$(head -1 $fResultats)"
fi
if [ ! $? = 0 ] ; then
zenity --info --title "Erreur" --text "Impossible de trouver le fichier $f" --timeout 5
fi
return 0
fi
res=$(mktemp ${S3F_TMP}/res_XXXXXXXX)
IFS=$'\n'
#~ cat $fResultats |
#~ zenity --width 1100 --height 500 --list \
#~ --title "Recherche : $lignecom" --text "Choisir une ou plusieurs lignes " \
#~ --multiple --column "Fichiers/dossiers" |
#~ tr '|' '\n' > $res
cat $fResultats |
zenity --width 1100 --height 500 --list \
--title "Recherche : $lignecom" --text "Choisir une ou plusieurs lignes " \
--multiple --column "Fichiers/dossiers" |
tr '|' '\n' > $res
# lancer chaque ligne sélectionnée
nbselect=0
while read rr
do
# limiter nb maxi pour ne pas surcharger machine
nbselect=$((nbselect+1))
echo nbselect=$nbselect
echo maxi_a_lancer=${maxi_a_lancer}
echo
if [ "${nbselect}" -gt "${maxi_a_lancer}" ] ; then
zenity --info --title Avertissement --text "Vous ne pouvez pas lancer plus de 10 lignes"
exit 1
else
# lancement xdg-open
if [ $lancerDIR = "TRUE" ] ; then
echo nemo "$(dirname "$rr")"
#~ xdg-open "$(dirname "$rr")"
nemo "$(dirname "$rr")"
else
echo xdg-open "$rr"
#~ xdg-open "$rr"
nemo "$rr"
fi
sleep 1
fi
done < $res
rm $res
# DEBUG ajouté en dernier (au cas où dysfonctionnement)
rm $fResultats
}
locmaj () {
for i in $(echo $dossiers | tr ';' ' ')
do
#nomcat=$(echo $i|sed 's/\//_/g')
if [ -d "$i" -a $(ls "$i" -l 2>/dev/null | wc -l) -gt 1 ] ; then
nomcat=$(echo $i|sed 's/\//_/g').updatedb
cd "$i"
echo "$(date +%c) updatedb --output=$DIR_CATALOGS/$nomcat --localpaths=$i ..."
echo "$(date +%H:%M:%S) [ OK ] $i"
#~ updatedb -l 0 -o $DIR_CATALOGS/$nomcat -U $i # version linux mint
updatedb --output=$DIR_CATALOGS/$nomcat --localpaths=$i 2>/dev/null # version ARM raspbian
else
echo "$(date +%H:%M:%S) [ABSENT] $i"
fi
done
# dossiers réseau pas acceptés par updatedb
# COORECTION : cf. option --netpaths='path1 path2...'
# https://man7.org/linux/man-pages/man1/updatedb.1.html
for i in $(echo $find_network | tr ';' ' ')
do
if [ -d "$i" -a $(ls "$i" -l 2>/dev/null | wc -l) -gt 1 ] ; then
nomcat=$(echo $i|sed 's/\//_/g').find_network.txt
cd "$i"
echo "$(date +%c) find $i -type f > $DIR_CATALOGS/$nomcat ..."
echo "$(date +%H:%M:%S) [ OK ] $i"
find $i -type f > $DIR_CATALOGS/$nomcat
else
echo "$(date +%H:%M:%S) [ABSENT] $i"
fi
done
echo "$(date +%H:%M:%S) update fini"
}
show_catalogs () {
echo
echo '#################
Variable dossiers
#################'
for i in $(echo $dossiers | tr ';' ' '); do
echo "- $i"
done
echo
echo '###################
ls -l $DIR_CATALOGS
###################'
ls -l $DIR_CATALOGS
echo "
Pour éditer la liste des catalogues,
modifier directement la variable dossiers dans
le script $0"
}
aide_s3f () {
echo "$(basename $0)"
echo " s3f = super fast file finder"
echo "Recherche ultra-rapide à partir de catalogues"
echo "créés avec updatedb."
echo "La recherche se fait avec locate (premier terme),"
echo "et grep (termes éventuels suivants)."
echo ""
echo "Utilisation : $(basename $0) [OPTION]... terme1 [terme2] [terme3] ..."
echo ""
echo "Options courtes :"
echo " -d dir (dossier)"
echo " affiche les résultats dans zenity, avec lancement du dossier de la ligne choisie"
echo " -D liste des dossiers indexés après avoir effacé l'écran"
echo " -h cette aide"
echo " -i interactif (interface graphique)"
echo " affiche une boîte de dialogue zenity demandant d'entrer la ligne de commande complète"
echo " -n nemo dans dossier catalogues"
echo " -N nemo dans dossier parent première ligne trouvée"
echo " -l lister"
echo " affiche les résultats dans le terminal (utile pour traitement par shell)"
echo " -L liste des dossiers indexés"
echo " -s start (lancer) [DEFAUT]"
echo " affiche les résultats dans zenity, avec lancement d'une ligne par double clic"
echo " -S lance la première ligne trouvée"
echo " -p presse-papier"
echo " -u update"
echo " mise à jour des catalogues définis dans la variable locale dossiers,"
echo " définies dans le script même."
echo " -U update et quitter console"
echo " -z interactif (interface graphique)"
echo ""
echo "Exemples :"
echo "s3f -u"
echo " met à jour les catalogues"
echo ""
echo "s3f scripts traitement image"
echo " recherche les fichiers dont le nom complet contient les mots"
echo " 'scripts' 'traitement' 'image' dans n'importe quel ordre,"
echo " et affiche la liste dans une fenêtre (zenity)."
echo " Double-cliquez sur un élément ou bien sélectionner plusieurs lignes"
echo " et appuyez sur Ouvrir."
echo ""
echo "s3f -d facture phon free"
echo " recherche les fichiers dont le nom complet contient les mots"
echo " 'facture' 'phon' 'free' dans n'importe quel ordre"
echo " et affiche la liste dans une fenêtre (zenity)."
echo " Double-cliquez sur un élément ou bien sélectionner plusieurs lignes"
echo " et appuyez sur Ouvrir pour ouvrir le dossier parent."
}
verif_dirs_catalogs () {
if [ ! -d $DIR_CATALOGS ] ; then
echo Le dossier $DIR_CATALOGS n\'existe pas. FIN.
echo Pour le créer, lancer ceci :
echo mkdir $DIR_CATALOGS
exit 1
fi
}
reprendre_histo () {
:
}
ligne_commande () {
# 0. premier contrôle : ligne de commande
if [ $# = 0 ] ; then
aide_s3f
return 0
fi
lignecom="$@"
#~ echo "$@" >> ${S3F_HISTO}
while getopts "defghilnsSpuULDzN" option
do
case "$option" in
l) # search / chercher dans fichiers textes des catalogues
afficher="FALSE"
shift $((OPTIND-1))
echo ON CHERCHE 1
on_cherche "$@"
[ $(wc -l < $fResultats) -eq 0 ] || cat $fResultats
rm $fResultats
exit 1
;;
D|L) #
clear
show_catalogs
exit 1
;;
d) # lancer dossiers
shift $((OPTIND-1)) # ici shift indispensable, ai reprendre tout code pour
lancerDIR="TRUE" # lancer opérations en-dehors du while getopts
afficher="TRUE"
echo ON CHERCHE 2
on_cherche "$@"
[ $(wc -l < $fResultats) -eq 0 ] || on_affiche_ou_lance_resultats
exit 1
;;
e) # search / chercher
echo ON CHERCHE 3
on_cherche "$@"
echo $EDITEUR $fResultats
$EDITEUR $fResultats
return 0
;;
f) # fuzzy search
banner fuzzy
banner en_cours
zenity --info --title Information --text "Option FUZZY En construction."
echo ON CHERCHE 4
on_cherche fuzzy "$@"
$EDITEUR $fResultats &
sleep 5
rm $fResultats
exit 1
;;
g) shift
recherche_gnome_search_tool "$@"
return 0
;;
h) # aide
aide_s3f
return 0
;;
i) interactif
return 0
;;
n) # nemo
nemo $DIR_CATALOGS
return 0
;;
s) # recherche [DEFAUT]
afficher="TRUE"
shift
echo ON CHERCHE AAA
lancer_rechercheA "$@"
return 0
;;
S) # recherche puis lancement 1er résultat
afficher="TRUE"
shift
recherche_puis_lancement_premier_resultat "$@"
return 0
;;
N) # recherche puis lancement 1er résultat
afficher="TRUE"
shift
recherche_puis_lancement_premier_resultat_dossier "$@"
return 0
;;
t) # lancer / launch [DEFAUT]
display_duration="TRUE"
;;
p) # relancer xst avec le presse-papier
if ! $(which xsel) ; then
echo Veuillez installer xsel
echo FIN
zenity --info --title Information --text "xsel n'est pas présent, veuillez l'installer"
exit
fi
#~ echo $0 "$(xsel -b | head -1 | cut -c-50)"
$0 "$(xsel -b)"
return 0
;;
u) locmaj
return 0
;;
U) locmaj
echo "kill -9 $PPID dans 1s"
sleep 1
kill -9 $PPID
return 0
;;
z) echo interactif
interactif
return 0
;;
esac
shift $((OPTIND-1))
done
# aucune option : par défaut on_cherche puis on_affiche_ou_lance_resultats
afficher="TRUE"
echo ON CHERCHE DEFAUT
lancer_rechercheA "$@"
}
recherche_puis_lancement_premier_resultat () {
afficher_MSG "recherche_puis_lancement_premier_resultat"
on_cherche "$@"
[ $(wc -l < $fResultats) -eq 0 ] || on_affiche_ou_lance_resultats "LANCER"
}
recherche_puis_lancement_premier_resultat_dossier () {
afficher_MSG "recherche_puis_lancement_premier_resultat_DOSSIER"
lancerDIR="TRUE"
on_cherche "$@"
[ $(wc -l < $fResultats) -eq 0 ] || on_affiche_ou_lance_resultats "LANCER"
}
lancer_rechercheA () {
afficher_MSG "lancer_rechercheA sur : $*"
on_cherche "$*"
on_affiche_ou_lance_resultats
}
recherche_gnome_search_tool () {
afficher_MSG "recherche_gnome_search_tool"
gnome-search-tool --path=$SEARCHDIR --start --sortby=date --named=$1
}
interactif () {
defaut="Entrez votre ligne de commande ici"
finter=${S3F_TMP}/s3f_interactif.interactif
if [ -f $finter ] ; then
defaut="$(cat $finter)"
fi
r="$(zenity --entry --title "s3f en mode interactif" --text "Veuillez taper votre ligne de commande" --entry-text="$defaut")"
if [ "x$r" = "x" ] ; then
echo "Recherche abandonnée"
return 0
fi
echo "$r" > $finter
$0 "$r"
}
afficher_MSG () {
echo "$@"
}
if [ ! -d $DIR_CATALOGS ]; then
echo "Le dossier $DIR_CATALOGS est absent."
else
which updatedb || echo Installation de locate nécessaire
which updatedb || sudo apt install locate
rm -rf /tmp/s3f # nettoyage d'une ancienne commande s3f
mkdir /tmp/s3f
ligne_commande "$@"
fi