string 如何使用Bash测试文件中是否存在字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4749330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test if string exists in file with Bash?
提问by Toren
I have a file that contains directory names:
我有一个包含目录名称的文件:
my_list.txt
:
my_list.txt
:
/tmp
/var/tmp
I'd like to check in Bash before I'll add a directory name if that name already exists in the file.
如果该名称已存在于文件中,我想在添加目录名称之前先检查 Bash。
回答by Thomas
grep -Fxq "$FILENAME" my_list.txt
The exit status is 0 (true) if the name was found, 1 (false) if not, so:
如果找到名称,退出状态为 0(真),否则为 1(假),因此:
if grep -Fxq "$FILENAME" my_list.txt
then
# code if found
else
# code if not found
fi
Explanation
解释
Here are the relevant sections of the man page for grep
:
以下是手册页grep
的相关部分:
grep [options] PATTERN [FILE...]
-F
,--fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.
-x
,--line-regexp
Select only those matches that exactly match the whole line.
-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.
grep [options] PATTERN [FILE...]
-F
,--fixed-strings
将 PATTERN 解释为由换行符分隔的固定字符串列表,其中任何一个都将被匹配。
-x
,--line-regexp
仅选择与整行完全匹配的那些匹配项。
-q
,--quiet
,--silent
安静的; 不要向标准输出写入任何内容。如果找到任何匹配项,即使检测到错误,也立即以零状态退出。另请参阅
-s
或--no-messages
选项。
Error handling
错误处理
As rightfully pointed out in the comments, the above approach silently treats error cases as if the string was found. If you want to handle errors in a different way, you'll have to omit the -q
option, and detect errors based on the exit status:
正如评论中正确指出的那样,上述方法默默地将错误情况视为找到了字符串。如果您想以不同的方式处理错误,则必须省略该-q
选项,并根据退出状态检测错误:
Normally, the exit status is 0 if selected lines are found and 1 otherwise. But the exit status is 2 if an error occurred, unless the
-q
or--quiet
or--silent
option is used and a selected line is found. Note, however, that POSIX only mandates, for programs such asgrep
,cmp
, anddiff
, that the exit status in case of error be greater than 1; it is therefore advisable, for the sake of portability, to use logic that tests for this general condition instead of strict equality with 2.
通常,如果找到选定的行,退出状态为 0,否则为 1。但如果发生错误,退出状态为 2,除非使用
-q
or--quiet
或--silent
选项并找到选定的行。但是请注意,这只是POSIX任务,为如程序grep
,cmp
以及diff
,在错误的情况下,退出状态大于1; 因此,为了可移植性,建议使用测试此一般条件的逻辑,而不是与 2 严格相等。
To suppress the normal output from grep
, you can redirect it to /dev/null
. Note that standard error remains undirected, so any error messages that grep
might print will end up on the console as you'd probably want.
要抑制 的正常输出grep
,您可以将其重定向到/dev/null
. 请注意,标准错误仍然是未定向的,因此任何grep
可能打印的错误消息都将如您所愿地显示在控制台上。
To handle the three cases, we can use a case
statement:
为了处理这三种情况,我们可以使用一个case
语句:
case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in
0)
# code if found
;;
1)
# code if not found
;;
*)
# code if an error occurred
;;
esac
回答by Kuf
Regarding the following solution:
关于以下解决方案:
grep -Fxq "$FILENAME" my_list.txt
In case you are wondering (as I did) what -Fxq
means in plain English:
如果您想知道(就像我一样)-Fxq
简单的英语是什么意思:
F
: Affects how PATTERN is interpreted (fixed string instead of a regex)x
: Match whole lineq
: Shhhhh... minimal printing
F
: 影响 PATTERN 的解释方式(固定字符串而不是正则表达式)x
: 匹配整行q
:嘘……最小的打印
From the man file:
从人文件:
-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.)
回答by Luca Borrione
Three methods in my mind:
我心目中的三种方法:
1) Short test for a name in a path (I'm not sure this might be your case)
1)对路径中的名称进行简短测试(我不确定这可能是您的情况)
ls -a "path" | grep "name"
2) Short test for a string in a file
2) 对文件中的字符串进行简短测试
grep -R "string" "filepath"
3) Longer bash script using regex:
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
This should be quickerif you have to test multiple string on a filecontent using a loop for example changing the regex at any cicle.
如果您必须使用循环测试文件内容上的多个字符串,例如在任何循环中更改正则表达式,这应该会更快。
回答by imwilsonxu
Simpler way:
更简单的方法:
if grep "$filename" my_list.txt > /dev/null
then
... found
else
... not found
fi
Tip: send to /dev/null
if you want command's exit status, but not outputs.
提示:/dev/null
如果您想要命令的退出状态,而不是输出,则发送到。
回答by Christian737
Easiest and simplest way would be:
最简单和最简单的方法是:
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
grep -c will return the count of how many times the string occurs in the file.
grep -c 将返回字符串在文件中出现的次数。
回答by lecodesportif
If I understood your question correctly, this should do what you need.
如果我正确理解了您的问题,这应该可以满足您的需求。
- you can specifiy the directory you would like to add through $check variable
- if the directory is already in the list, the output is "dir already listed"
- if the directory is not yet in the list, it is appended to my_list.txt
- 您可以通过 $check 变量指定要添加的目录
- 如果目录已在列表中,则输出为“目录已列出”
- 如果目录尚未在列表中,则将其附加到 my_list.txt
In one line: check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
在一行中:check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
回答by gordon
If you just want to check the existence of one line, you do not need to create a file. E.g.,
如果只想检查一行是否存在,则不需要创建文件。例如,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ; then
# code for if it exists
else
# code for if it does not exist
fi
回答by Rudy
My version using fgrep
我的版本使用 fgrep
FOUND=`fgrep -c "FOUND" $VALIDATION_FILE`
if [ $FOUND -eq 0 ]; then
echo "Not able to find"
else
echo "able to find"
fi
回答by David Okwii
grep -E "(string)" /path/to/file || echo "no match found"
-E option makes grep use regular expressions
-E 选项使 grep 使用正则表达式
回答by AndrewD
A grep-less solution, works for me:
一个 grep-less 解决方案,对我有用:
MY_LIST=$( cat /path/to/my_list.txt )
if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
echo "It's there!"
else
echo "its not there"
fi