В дополнение к ответу Даниэля вы также, похоже, запрашиваете список файлов, в которых слово встречается только один раз. Для этого я продолжил бы запускать FindList
во всех файлах
res =FindList[filelist, "love"]
Затем уменьшите результаты до однострочных, через
lines = Select[ res, Length[#]==1& ]
Но это не исключает случаев, когда в одной строке более одного вхождения. Для этого вы можете использовать StringCount
и принимать только те случаи, когда он равен 1, как показано ниже
Select[ lines, StringCount[ #, RegularExpression[ "\\blove\\b" ] ] == 1& ]
RegularExpression
указывает, что слово «любовь» должно быть отдельным словом, использующим маркер границы слова (\\b
), так что слова типа «прекрасный» не будут включены.
Редактировать : Похоже, что FindList
при передаче списка файлов возвращает плоский список, поэтому вы не можете определить, какой элемент идет с каким файлом. Например, если у вас есть 3 файла и они содержат слова «любовь» 0, 1 и 2 раза соответственно, вы получите список, который выглядит как
{, love, love, love }
что явно не полезно. Чтобы преодолеть это, вам придется обрабатывать каждый файл отдельно, и это лучше всего сделать с помощью Map
(/@
), как указано ниже
res = FindList[#, "love"]& /@ filelist
, а остальная часть приведенного выше кода работает как положено.
Но, если вы хотите связать результаты с именем файла, вам нужно его немного изменить.
res = {#, FindList[#, "love"]}& /@ filelist
lines = Select[res,
Length[ #[[2]] ] ==1 && (* <-- Note the use of [[2]] *)
StringCount[ #[[2]], RegularExpression[ "\\blove\\b" ] ] == 1&
]
, который возвращает список вида
{ {filename, { "string with love in it" },
{filename, { "string with love in it" }, ...}
Чтобы извлечь имена файлов, вы просто набираете lines[[All, 1]]
.
Обратите внимание, чтобы Select
на свойства, которые вы хотели, я использовал Part
([[ ]]
), чтобы указать второй элемент в каждом элементе данных, и то же самое касается извлечения файла имена.