如何使用Bash测试文件中是否存在字符串?

Tor*_*ren 304 string bash file

我有一个包含目录名称的文件:

my_list.txt :

/tmp
/var/tmp
Run Code Online (Sandbox Code Playgroud)

我想在我添加目录名之前检查Bash,如果该名称已存在于文件中.

Tho*_*mas 595

grep -Fxq "$FILENAME" my_list.txt
Run Code Online (Sandbox Code Playgroud)

如果找到名称,则退出状态为0(true),否则为1(false),因此:

if grep -Fxq "$FILENAME" my_list.txt
then
    # code if found
else
    # code if not found
fi
Run Code Online (Sandbox Code Playgroud)

以下是手册页grep的相关部分:

grep [options] PATTERN [FILE...]
Run Code Online (Sandbox Code Playgroud)

  • @Toren可以使用`$?`访问最近的退出状态.你也可以使用grep命令和`if`语句(如更新的答案中所示). (6认同)
  • 您可以使用`grep -Fqx"$ FILENAME"`并且您不必担心变量内容中的正则表达式字符,您不必在搜索字符串中使用它们. (5认同)
  • 给人们看这个答案的几个注释:1)在bash中,0总是为真,其他任何东西都是假的2)如果你想让整行完全匹配,只使用-x标志.如果您只想查找文件中是否存在字符串,请将其保留.如果你想确定你的字符串是否存在但是必须没有匹配整行(即整个单词),请使用-w. (4认同)
  • 如果我从bash脚本执行此命令如何将0或1捕获到变量中? (2认同)

Kuf*_*Kuf 86

关于以下解决方案:

grep -Fxq "$FILENAME" my_list.txt
Run Code Online (Sandbox Code Playgroud)

万一你想知道(就像我一样)-Fxq用简单的英语表示什么:

  • F:影响PATTERN的解释方式(固定字符串而不是正则表达式)
  • x:匹配整条线
  • q:Shhhhh ......印刷很少

从man文件:

-F, --fixed-strings
    Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of which is to be matched.
    (-F is specified by POSIX.)
-x, --line-regexp
    Select only those matches that exactly match the whole line.  (-x is specified by POSIX.)
-q, --quiet, --silent
    Quiet; do not write anything to standard output.  Exit immediately with zero status  if  any  match  is
          found,  even  if  an error was detected.  Also see the -s or --no-messages option.  (-q is specified by
          POSIX.)
Run Code Online (Sandbox Code Playgroud)

  • -F不影响文件处理,它会影响PATTERN的解释方式.通常,PATTERN被解释为正则表达式,但是使用-F它将被解释为固定字符串. (5认同)

Luc*_*one 38

我心中有三种方法:

1)对路径中的名称进行简短测试(我不确定这可能是您的情况)

ls -a "path" | grep "name"
Run Code Online (Sandbox Code Playgroud)


2)对文件中的字符串进行简短测试

grep -R "string" "filepath"
Run Code Online (Sandbox Code Playgroud)


3)使用正则表达式的更长的bash脚本:

#!/bin/bash

declare file="content.txt"
declare regex="\s+string\s+"

declare file_content=$( cat "${file}" )
if [[ " $file_content " =~ $regex ]] # please note the space before and after the file content
    then
        echo "found"
    else
        echo "not found"
fi

exit
Run Code Online (Sandbox Code Playgroud)

如果您必须使用循环测试文件内容上的多个字符串,例如更改任何cicle上的正则表达式,这应该更快.

  • 为什么在$ file_contenet之前和之后需要空格? (10认同)

imw*_*nxu 16

更简单的方法:

if grep "$filename" my_list.txt > /dev/null
then
   ... found
else
   ... not found
fi
Run Code Online (Sandbox Code Playgroud)

提示:/dev/null如果您想要命令的退出状态而不是输出,则发送到.


GTo*_*rov 11

这是搜索和评估字符串或部分字符串的快速方法:

if grep -R "my-search-string" /my/file.ext
then
    # string exists
else
    # string not found
fi
Run Code Online (Sandbox Code Playgroud)

您还可以先测试命令是否返回任何结果,只需运行:

grep -R "my-search-string" /my/file.ext
Run Code Online (Sandbox Code Playgroud)

  • 我建议添加 -q ,这样您就不会在标准输出中获取找到的字符串 (2认同)

小智 9

最简单最简单的方法是:

isInFile=$(cat file.txt | grep -c "string")


if [ $isInFile -eq 0 ]; then
   #string not contained in file
else
   #string is in file at least once
fi
Run Code Online (Sandbox Code Playgroud)

grep -c将返回字符串在文件中出现次数的计数.


Dav*_*wii 6

grep -E "(string)" /path/to/file || echo "no match found"
Run Code Online (Sandbox Code Playgroud)

-E 选项使 grep 使用正则表达式


lec*_*tif 5

如果我理解你的问题,这应该做你需要的.

  1. 您可以通过$ check变量指定要添加的目录
  2. 如果目录已在列表中,则输出为"已列出的目录"
  3. 如果目录尚未在列表中,则将其附加到my_list.txt

在一行中:check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt


Ing*_*n29 5

由于某种原因,@Thomas 的解决方案对我不起作用,但我有更长的带有特殊字符和空格的字符串,所以我只是更改了参数,如下所示:

if grep -Fxq 'string you want to find' "/path/to/file"; then
    echo "Found"
else
    echo "Not found"
fi
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助某人