Note : les fichiers textes doivent être encodés avec le format " UTF8 "encodage.
Voici un premier script :
Exemple : Les mots-clés :
"Bill
Bob
Joe"
fgrep y trier lignes de retour, comme ceci :
/path/of/thisFile.txt:Bill
/path/of/thisFile.txt:Bob
/path/of/thisFile.txt:Joe
/path/of/thisFile2.txt:Bob
/path/of/thisFile2.txt:Joe
/path/of/thisFile3.txt:Bob
/path/subf1/of/some_File.txt:Bill
/path/subf3/of/some_xzzz_File.txt:Bill
Le script utilise une boucle pour vérifier le chemin de chaque élément de cette liste.
Le script récupère le chemin d'accès du premier élément, il enlève ":Bill" à la fin de la ligne --> le chemin d'accès est donc " /path/of/thisFile.txt ".
Le script vérifie l'élément (index actuel + le nombre de mots-clés -1), c'est le troisième élément, donc le troisième élément contient le même chemin, puis le script ajoute le chemin dans une nouvelle liste.
Les autres éléments ne contiennent pas tous les mots-clés.
set r to text returned of (display dialog "What keywords?" default answer "Joe Bill Bob") --- each keyword must be sepearated by a space
set tKeys to my makeKeysForGrep(r)
if tKeys is not "" then
set masterFolder to choose folder with prompt "Select the source folder .."
set filesList to my getFilescontainingKeywords(masterFolder, tKeys) -- get a list of files ( each file contains all the keywords)
--do something with the filesList -- this list contains path of type 'posix path'
end if
on makeKeysForGrep(t)
(*** delete trailing and leading spaces, replace multiple spaces in a row by one space (clean the string to avoid issue with the unnecessary spaces in the grep command),
and replace the space character by a linefeed character , so each line contains a keyword. ***)
set r to do shell script "perl -pe 's/ +$|^ +//g; s/ +/ /g; s/ /\\n/g; ' <<< " & (quoted form of t) & "| sort -u" without altering line endings
if r is not linefeed then return text 1 thru -2 of r -- remove the last line (it's a blank line)
return "" -- r is a a blank line, so return ""
end makeKeysForGrep
on getFilescontainingKeywords(dir, tKeys)
script o
property tfiles : {}
end script
set numOfKeywords to count (paragraphs of tKeys) -- get the number of keywords
set tFolder to quoted form of POSIX path of dir
set o's tfiles to do shell script "fgrep -R -o -w --include \"*.txt\" " & (quoted form of tKeys) & " " & tFolder & " | sort -u"
-- fgrep return the full path + ":" + the keyword, sort -u : sort the paths and deletes duplicate lines (because the same file can contains multiple occcurences of a keyword)
if o's tfiles is not "" then
if numOfKeywords = 1 then return o's tfiles -- no need to continue because one keyword only, return all Files
set l to {}
set o's tfiles to paragraphs of o's tfiles
set tc to count o's tfiles
set firstKeyword to ":" & (paragraph 1 of tKeys)
set numCh to (length of firstKeyword) + 1
set i to 1
repeat while (i < tc) -- check each path in the list, the same path must exists numOfKeywords in a row
set thisItem to (item i of o's tfiles)
if thisItem ends with firstKeyword then
set textFilepath to text 1 thru -numCh of thisItem
set j to (i + numOfKeywords - 1)
if j > tc then exit repeat
if (item j of o's tfiles) starts with textFilepath then -- this file contains all the keywords
set end of l to textFilepath --- append this path to the list
set i to i + numOfKeywords -- to skip items wich contains the same path
else
set i to i + 1 -- next file
end if
else
set i to i + 1 -- next file
end if
end repeat
return l -- list of files which contains all the keywords
end if
return {} -- No files found
end getFilescontainingKeywords
Les options de fgrep
:
-
En --include \"*.txt\"
option : seuls les fichiers correspondant au sont recherchés, donc tous les noms qui se terminent par " .txt "
En -w
option : ne correspond qu'à un mot, donc Bob ne correspond pas Bobby , supprimez cette option si vous souhaitez faire correspondre une sous-chaîne du texte.
En -R
option : Recherche récursive dans les sous-répertoires, supprimer cette option si vous ne voulez pas de récursivité.
Ajouter le -i
pour effectuer une correspondance insensible à la casse. Par défaut par défaut, fgrep
est sensible à la casse.