Nota : i file di testo devono essere codificati con la codifica " UTF8 ".
Ecco uno script iniziale:
Esempio : le parole chiave:
"Bill
Bob
Joe"
fgrep e ordina righe di ritorno, come questo:
/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
Lo script usa un ciclo per controllare il percorso di ogni elemento in questo elenco.
Lo script prende il percorso dal primo elemento, rimuove ": Bill" alla fine della riga - > quindi il percorso è " /path/of/thisFile.txt ".
Lo script controlla l'elemento (indice corrente + il numero di parole chiave -1), è il terzo elemento, quindi il terzo elemento contiene lo stesso percorso, quindi lo script aggiunge il percorso in un nuovo elenco
Gli altri elementi non contengono tutte le parole chiave.
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
Le opzioni di fgrep
:
-
L'opzione --include \"*.txt\"
: solo i file che corrispondono al dato
vengono cercati i nomi dei file, quindi qualsiasi nome che termini con " .txt "
L'opzione -w
: corrisponde solo alla parola, quindi Bob non corrisponde a Bobby ,
rimuovi questa opzione se vuoi abbinare una sottostringa nel testo.
L'opzione -R
: cerca ricorsivamente sottodirectory, rimuovi questo
opzione se non vuoi ricorsione.
Aggiungi l'opzione -i
per eseguire la corrispondenza senza distinzione tra maiuscole e minuscole. Di
predefinito, fgrep
è case sensitive.