如何将 grep 命令的字符串搜索放入 if 语句中?

如何将 grep 命令的字符串搜索放入 if 语句中?

我想在两个文件中搜索多个字符串。如果在两个文件中都找到一个字符串,则进行一些操作。如果仅在一个文件中找到一个字符串,则进行另一件事。

我的命令如下:

####This is for the affirmative sentence in both files
if grep -qw "$users" "$file1" && grep -qw "$users" "$file2"; then

####This is for the affirmative sentence in only one file, and negative for the other one
if grep -qw "$users" "$file1" ! grep -qw "$users" "$file2"; then

否认和肯定陈述的方式正确吗? pd 我正在使用 KSH shell。

先感谢您。

答案1

另外一个选择:

grep -qw -- "$users" "$file1"; in_file1=$?
grep -qw -- "$users" "$file2"; in_file2=$?

case "${in_file1},${in_file2}" in
    0,0) echo found in both files ;;
    0,*) echo only in file1 ;;
    *,0) echo only in file2 ;;
      *) echo in neither file ;;
esac

答案2

尝试这个:

if grep -wq -- "$user" "$file1" && grep -wq -- "$user" "$file2" ; then
   echo "string avail in both files"
elif grep -wq -- "$user" "$file1" "$file2"; then
   echo "string avail in only one file"
fi
  • grep 可以在多个文件中搜索模式,因此无需使用 OR/NOT 运算符。

答案3

n=0

#Or if you have more files to check, you can put your while here. 
grep -qw -- "$users" "$file1" && ((n++))
grep -qw -- "$users" "$file2" && ((n++))

case $n in 
   1) 
       echo "Only one file with the string"
    ;;
   2)
       echo "The two files are with the string"
   ;;
   0)
       echo "No one file with the string"
   ;;
   *)
       echo "Strange..."
   ;;
esac 

注意:((n++))是 ksh 扩展(也受zsh和支持bash)。在 POSIXsh语法中,您需要n=$((n + 1))改为。

答案4

如果您的文件名不包含换行符,您可以grep通过让 grep 打印匹配文件的名称并对结果进行计数来避免多次调用 。

 local IFS=$'\n'    # inside a function.  Otherwise use some other way to save/restore IFS
 matches=( $(grep -lw "$users" "$file1" "$file2") )

比赛场次为"${#matches[@]}"

这里可能有一种使用方法grep --null -lw,但我不确定如何解析输出。 Bashvar=( array elements )没有办法使用\0分隔符来代替\n。也许 bash 的mapfile内置函数可以做到这一点?但可能不是,因为您用 指定分隔符-d string


你可以count=$(grep -l | wc -l),但是你有两个外部进程,所以你最好grep分别运行这两个文件。 (与启动单独进程的 fork+exec + 动态链接器内容相比,启动开销grep与启动开销之间的差异wc很小)。

还有,跟wc -l你没发现哪个文件匹配。


通过数组中捕获的结果,这可能已经是您想要的,或者如果正好有 1 个匹配,您可以检查它是否是第一个输入。

local IFS=$'\n'    # inside a function.  Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )

# print the matching filenames
[[ -n $matches ]] && printf  'match in %s\n'  "${matches[@]}"

# figure out which input position the name came from, if there's exactly 1.
if [[ "${#matches[@]" -eq 1 ]]; then
    if [[ $matches == "$file1" ]];then
        echo "match in file1"
    else
        echo "match in file2"
    fi
fi

$matches${matches[0]}是第一个数组元素的简写。

相关内容