Найти текстовый файл, содержащий заданный текст, игнорируя новые строки и пробелы?

У меня есть строка вроде: "thisissometext". Я хочу найти все текстовые файлы в данном каталоге (рекурсивно), которые связываются с этой строкой, или любые ее вариации с пробелами и / или символами новой строки в середине. Например, текстовый файл, содержащий "this is sometext" или "this\n issometext", "this\n isso metext", должен отображаться в поиске. Как я могу это сделать?

3
задан 29 May 2015 в 20:45

4 ответа

С более новыми версиями GNU grep (который имеет -z опция), можно использовать этот лайнер:

find . -type f -exec grep -lz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' {} +

Рассмотрение пробелов может произойти промежуточное слова только.

Если Вы просто хотите искать все файлы, рекурсивно начинающие с текущего каталога, Вам не нужно find, можно просто использовать grep -r (рекурсивный). find может использоваться, чтобы быть выборочным на файлах, чтобы искать, например, выбрать файлы который каталог исключить. Так, просто:

grep -rlz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' .
  • Основной прием здесь -z, это будет рассматривать каждую строку входного потока, законченного в ASCII NUL вместо новой строки, в результате мы можем соответствовать новым строкам при помощи обычных методов.

  • [[:space:]] шаблон класса символов указывает на любые пробельные символы включая пространство, вкладку, CR, LF и т.д. Так, мы можем использовать его для соответствия всем пробельным символам, которые могут прибыть промежуточные слова.

  • grep -l распечатает только имена файлов что, имея любой из желаемых шаблонов. Если Вы хотите распечатать соответствия также, использовать -H вместо -l.

С другой стороны, если бы пробелы могут прибыть в какие-либо места, а не слова, это освободило бы его хороший взгляд:

grep -rlz
't[[:space:]]*h[[:space:]]*i[[:space:]]*s[[:space:]]*i[[:space:]]*\
s[[:space:]]*s[[:space:]]*o[[:space:]]*m[[:space:]]*e[[:space:]]*\
t[[:space:]]*e[[:space:]]*x[[:space:]]*t' .

С -P Опция (PCRE) можно заменить [[:space:]] с \s (это выглядело бы намного более хорошим):

grep -rlzP 't\s*h\s*i\s*s\s*i\s*s\s*s\s*o\s*m\s*e\s*\
t\s*e\s*x\s*t' .

Используя предложение @steeldriver для получения sed генерировать шаблон для нас было бы наилучшим вариантом:

grep -rlzP "$(sed 's/./\\s*&/2g' <<< "thisissometext")" .
10
ответ дан 29 May 2015 в 20:45

Код ниже ищет каталог рекурсивно файлы, удаляет все случаи " " и "\n". Если строка существует в оставшемся тексте, существует соответствие. Это подразумевает, что пробелы/новые строки могут быть на любом положении в строке в Вашем файле (файлах).

Что это делает

Если это найдет соответствие файлам, то они будут распечатаны в терминале, включая их пути, как:

/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt

Попытка / кроме я встроил, чтобы препятствовать тому, чтобы сценарий повредился, если это сталкивается с нечитабельным файлом.

Сценарий

#!/usr/bin/env python3
import os
import sys

s = sys.argv[2]
for root, dirs, files in os.walk(sys.argv[1]):
    for file in files:
        file = root+"/"+file
        try:
            if s in open(file).read().replace(" ", "").replace("\n",""):
                print(file)
        except:
            pass

Как использовать

  1. Скопируйте сценарий в пустой файл, сохраните его как find_string.py
  2. Выполните его с каталогом и строкой как аргументы:

    python3 /path/to/find_string.py <directory> <string_to_find>
    

    Если или строка или каталог содержат пробелы, используйте кавычки:

    python3 /path/to/find_string.py '<directory>' '<string_to_find>'
    

Примечание:

Сценарий, поскольку это - файлы находок со строкой, или с пробелами или с новыми строками в нем. Это может быть расширено с другими символами/строками (например, вкладки) в строке:

if s in open(file).read().replace(" ", "").replace("\n",""):
1
ответ дан 29 May 2015 в 20:45

Вы могли использовать grep -i --recursive 'word1\|word2' *, и awk '/word1/,/word2/' может использоваться для контакта с новой строкой

enter image description here

0
ответ дан 29 May 2015 в 20:45

Можно удалить весь пробел и grep это:

tr -d '[[:space:]]' < foo | grep thisissometext

Расширение:

find . -type f -exec bash -c 'for i; do tr -d "[[:space:]]" < "$i" | grep -q thisissometext && printf "%s\n" "$i"; done' _ {} +

Эти bash команда, расширенная:

for i
do
    tr -d "[[:space:]]" < "$i" | 
      grep -q thisissometext && 
      printf "%s\n" "$i"
done

Это циклично выполняется по всем аргументам и использует вышеупомянутый тест.

0
ответ дан 29 May 2015 в 20:45

Другие вопросы по тегам:

Похожие вопросы: