检查文件中是否存在所有多个字符串或正则表达式

2024-03-28

我想检查一下是否all我的字符串存在于文本文件中。它们可以存在于同一行或不同行上。部分匹配应该没问题。像这样:

...
string1
...
string2
...
string3
...
string1 string2
...
string1 string2 string3
...
string3 string1 string2
...
string2 string3
... and so on

在上面的示例中,我们可以用正则表达式代替字符串。

例如,以下code https://stackoverflow.com/a/4749368/6862601检查是否any我的字符串存在于文件中:

if grep -EFq "string1|string2|string3" file; then
  # there is at least one match
fi

如何检查是否all其中存在吗?因为我们只对presence在所有匹配项中,一旦所有字符串都匹配,我们就应该停止读取文件。

是否可以在不调用的情况下做到这一点grep多次(当输入文件很大或者我们有大量要匹配的字符串时不会缩放)或使用类似的工具awk or python?

另外,是否有一个可以轻松扩展正则表达式的字符串解决方案?


awk 是发明 grep、shell 等的人发明的工具,用于执行此类一般文本操作工作,因此不确定为什么您要尝试避免使用它。

如果您正在寻找简洁性,这里有 GNU awk 一行代码来完成您所要求的操作:

awk 'NR==FNR{a[$0];next} {for(s in a) if(!index($0,s)) exit 1}' strings RS='^$' file

这里还有很多其他信息和选项:

假设你真的在寻找字符串,那就是:

awk -v strings='string1 string2 string3' '
BEGIN {
    numStrings = split(strings,tmp)
    for (i in tmp) strs[tmp[i]]
}
numStrings == 0 { exit }
{
    for (str in strs) {
        if ( index($0,str) ) {
            delete strs[str]
            numStrings--
        }
    }
}
END { exit (numStrings ? 1 : 0) }
' file

一旦所有字符串匹配,上面的代码将停止读取文件。

如果您正在寻找正则表达式而不是字符串,那么使用 GNU awk 进行多字符 RS 并在 END 部分保留 $0 ,您可以这样做:

awk -v RS='^$' 'END{exit !(/regexp1/ && /regexp2/ && /regexp3/)}' file

实际上,即使它是字符串,你也可以这样做:

awk -v RS='^$' 'END{exit !(index($0,"string1") && index($0,"string2") && index($0,"string3"))}' file

上述 2 个 GNU awk 解决方案的主要问题是,像 @anubhava 的 GNU grep -P 解决方案一样,整个文件必须一次读入内存,而使用上面的第一个 awk 脚本,它可以在任何 awk 中工作任何 UNIX 机器上的任何 shell,一次仅存储一行输入。

我看到您在问题下添加了一条评论,表示您可能有数千个“模式”。假设您的意思是“字符串”,那么您可以从文件中读取它们,而不是将它们作为参数传递给脚本,例如使用用于多字符 RS 的 GNU awk 和每行一个搜索字符串的文件:

awk '
NR==FNR { strings[$0]; next }
{
    for (string in strings)
        if ( !index($0,string) )
            exit 1
}
' file_of_strings RS='^$' file_to_be_searched

对于正则表达式它是:

awk '
NR==FNR { regexps[$0]; next }
{
    for (regexp in regexps)
        if ( $0 !~ regexp )
            exit 1
}
' file_of_regexps RS='^$' file_to_be_searched

如果您没有 GNU awk 并且您的输入文件不包含 NUL 字符,那么您可以通过使用获得与上面相同的效果RS='\0'代替RS='^$'或者在读取变量时一次追加一行,然后在 END 部分处理该变量。

如果您的 file_to_be_searched 太大而无法放入内存,那么对于字符串来说就是这样:

awk '
NR==FNR { strings[$0]; numStrings=NR; next }
numStrings == 0 { exit }
{
    for (string in strings) {
        if ( index($0,string) ) {
            delete strings[string]
            numStrings--
        }
    }
}
END { exit (numStrings ? 1 : 0) }
' file_of_strings file_to_be_searched

以及正则表达式的等效项:

awk '
NR==FNR { regexps[$0]; numRegexps=NR; next }
numRegexps == 0 { exit }
{
    for (regexp in regexps) {
        if ( $0 ~ regexp ) {
            delete regexps[regexp]
            numRegexps--
        }
    }
}
END { exit (numRegexps ? 1 : 0) }
' file_of_regexps file_to_be_searched
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检查文件中是否存在所有多个字符串或正则表达式 的相关文章

  • awk 中的并行处理?

    awk 逐行处理文件 假设每行操作不依赖于其他行 有没有办法让 awk 一次并行处理多行 是否有其他文本处理工具可以自动利用并行性并更快地处理数据 唯一尝试提供 awk 并行实现的 awk 实现是并行 awk http code googl
  • 使用 netcat 提供包含图像的 HTTP 响应

    我正在尝试使用 netcat 编写一个小型 HTTP 服务器 对于纯文本文件 这工作正常 但当我尝试发送图片时 浏览器仅显示损坏图像的图标 我所做的就是提取所请求文件的 mime 类型和大小 并将其发送给客户端 我的示例图片的请求标头如下所
  • Google 自定义搜索引擎未给出预期的搜索结果

    我一直在尝试创建一个新的谷歌自定义搜索引擎 但是当我尝试一些查询时 搜索引擎没有给我预期的搜索 结果 在某些查询上它工作正常 但在其他查询上 它说 没有结果 我尝试添加我想要搜索的网站的 URL 但是当我尝试搜索该页面的关键字时 某些页面和
  • 将文件列表传递给 grep

    我有一个文件中的文件列表 该列表很大 并且文件名是非标准的 这意味着 有些文件名包含空格 非 ascii 字符 引号 单引号 所以 通过那个huge不能选择将文件列表作为 grep 参数 因为我不确定我不会超过linux允许的参数长度 我想
  • 更改grep命令的分隔符

    我在用grep检测 a href xxxx something here a 当链接在输入中分成两行时 这不起作用 我想 grep 检查直到它检测到但现在它只是将输入输入到 grep 中 直到检测到新行为止 所以如果输入是这样的 a hre
  • 在 shell 脚本中禁止输出到屏幕

    你好 我写了一个小脚本 usr bin ksh for i in DAT do awk BEGIN OFS FS 3 353 3 353861958962 print i gt gt i changed awk 3 353 i change
  • 如何在 AOSP 中向预构建应用程序(无源代码)添加额外权限

    我有一个没有特定 android 权限的应用程序 例如android permission CHANGE CONFIGURATION 我没有它的源代码 我正在开发 AOSP 我预先构建了这个应用程序 如下所示 将APK放入 device m
  • 如何从纯文本中查找键值存储中的值

    给定一个纯文本文件 其中包含 FOO foo BAR bar BAZ baz 我们如何grep使用键获取值 Use a 向后看 https regex101 com r q3FNpe 1 grep Po lt FOO w file foo
  • 如何区分 git 分支名称和提交哈希?

    我有一个 bash 脚本 它接受分支名称 例如 master 或 feature foo 或提交哈希 例如 1234abcd 的字符串 我已签出存储库 因此我可以调用 git 确定字符串是分支名称还是提交哈希的最佳方法是什么 bin bas
  • -bash: /usr/bin/virtualenvwrapper.sh: 没有这样的文件或目录

    我无法弄清楚 shell 试图在哪里运行 usr bin virtualenvwrapper sh服务器登录时 我希望 virtualenvwrapper 永久卸载 而不仅仅是从 shell 实例中删除 我以为我卸载了它pip uninst
  • 从 Bash 调用的 Expect 脚本的退出状态代码

    我制作了一个 Bash 脚本 它使用 Expect 脚本来自动进行 ssh 登录 该脚本连接到多个服务器并运行一些命令 bash 脚本会提示输入一次登录凭据 我想合并一个功能 其中如果第一个服务器登录失败 脚本将终止 以避免脚本检查下一个服
  • 使用 bash 解析 ICS 文件

    这是一个谷歌日历 ics 文件 我每次都会下载它来检查是否有新的比赛事件被添加或更改 并且我出现在IRC上 我需要转换这样的文件 BEGIN VEVENT DTSTART 20160612T201000Z DTEND 20160612T21
  • 如何使用 grep 查找文件夹内的单词?

    在 Windows 中 我会进行搜索以在文件夹中查找单词 同样 我想知道某个特定单词是否出现在包含许多子目录和文件的目录中 我对 grep 语法的搜索显示我必须指定文件名 即grep string filename Now I do not
  • Git:确定分支是否处于合并冲突状态

    我正在编写一个 bash 脚本来进行一些自动化操作 该脚本的一部分涉及导航到本地存储库 切换到本地 master 分支 然后拉取远程 master 以使用最新代码更新本地 master 分支 有谁知道是否有一种方法可以以编程方式确定拉取是否
  • 使用“touch”创建目录? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 1 在 A 目录中 find type f gt a txt 2 在 B 目录中 cat a txt while read FILENAMES do
  • 使用 grep 仅打印上下文

    Using grep http www computerhope com unix ugrep htm 您可以打印与您的搜索查询匹配的行 添加一个 C选项将打印两行周围的上下文 如下所示 gt grep C 2 lorem some con
  • 如何使用AWK从文件中连续输出行

    我有一个多行文件 我想连续输出文件的某些行 比如第一次 从第1行打印到第5行 下次 打印第2行到第6行 依此类推 我发现 AWK 是一个非常有用的函数 我尝试自己编写代码 但它什么也没输出 以下是我的代码 bin bash for n in
  • Shell 脚本对文件进行计数,然后删除最旧的文件

    我是 shell 脚本新手 所以我需要一些帮助 我有一个充满备份的目录 如果我有超过 10 个备份文件 我想删除最旧的文件 以便仅留下 10 个最新的备份文件 到目前为止 我知道如何计算文件数 这看起来很简单 但是如果计数超过 10 我该如
  • 强制节点在 Windows 上使用 git bash

    我有一个 package json 文件 如下所示 name APP version 3 0 0 private true scripts start node app js test test dbLoad env db test tes
  • 为什么 PS1 不更新 git 分支名称?

    PS1 w git branch grep cut b 3 100 我按上面设置我的 PS1 但在我更改分支后 它不会更新提示中的分支名称git checkout 或使用以下命令更改存储库cd 如何解决这个问题 当反引号引用位被评估时PS1

随机推荐