![查找包含给定文本的文本文件,忽略新行和空格?](https://linux22.com/image/1126834/%E6%9F%A5%E6%89%BE%E5%8C%85%E5%90%AB%E7%BB%99%E5%AE%9A%E6%96%87%E6%9C%AC%E7%9A%84%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%EF%BC%8C%E5%BF%BD%E7%95%A5%E6%96%B0%E8%A1%8C%E5%92%8C%E7%A9%BA%E6%A0%BC%EF%BC%9F.png)
我有一个字符串,例如:"thisissometext"
。我想(递归地)查找给定目录中包含此字符串或其中间有空格和/或换行符的任何变体的所有文本文件。例如,包含"this is sometext"
、 或 的"this\n issometext"
文本文件"this\n isso metext"
应显示在搜索中。我该怎么做?
答案1
使用较新版本的 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")" .
答案2
您可以删除所有空格并对其进行 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
这将循环遍历所有参数并使用上述测试。
答案3
下面的代码递归搜索目录中的文件,删除所有出现的" "
和"\n"
。如果字符串存在于剩余文本中,则匹配。这意味着空格/换行符可以放在任何在文件内的字符串中的位置。
它能做什么
如果找到匹配的文件,它们将被打印在终端中,包括它们的路径,例如:
/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt
我内置了 try / except 以防止脚本在遇到不可读的文件时中断。
剧本
#!/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
如何使用
- 将脚本复制到一个空文件中,另存为
find_string.py
使用目录和字符串作为参数来运行它:
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",""):
答案4
您可以使用grep -i --recursive 'word1\|word2' *
并awk '/word1/,/word2/'
可以用来处理换行符