使用 "for" in shell 遍历文件中的行从不匹配目标

Iterating over lines in a file with "for" in shell never matching target

我写了一个 shell 脚本,如您所见。该脚本读取 .dat 文件中的所有行,并根据指定的参数写入屏幕匹配词,但 if/else 块不会 properly.Both 块 if and else 同时触发。

sh 文件

#!/bin/bash
p="*.dat"
k=""
for f in $p
do
    if [ "$k" == "$f" ]; then
        echo "$f present"
    else
        echo "not found $k"
    fi
    cat $f
done

dat 文件

lorem
ipsum
loremium
dolor
sit
amet
ipso

终端机

$ ./loc.sh lor

结果

not found lor
lorem
ipsum
loremium
dolor
sit
amet
ipso

直到 运行 比较之后,原始代码才查看文件内部——它只是比较 name[=每个 .dat 文件的 43=] 到目标,并且只允许完全匹配(不是子字符串)。

改为考虑:

while read -r line; do
  if [[ $line = *""* ]]; then
    echo " present in $line"
  else
    echo " not found in $line"
  fi
done < <(cat *.dat)
  • 使用cat *.dat 将所有文件合并为一个流。将其包含在 <(cat *.dat) 中会生成一个文件名,可以从中读取该文件名以生成该流;使用 < <(cat *.dat) 从此文件重定向标准输入(在发生此重定向的 while 循环的范围内)。
  • 使用 while read 逐行处理输入流(参见 BashFAQ #1)。
  • 使用 [[ $line = *""* ]] 的测试允许在 行中找到目标(</code> 的内容),而不是仅在 <code> 匹配整行作为一个整体。您也可以使用 [[ $line =~ "" ]] 实现此效果。 请注意,在任何一种情况下,引号都是正确操作所必需的。
  • 使用 for 循环遍历行是非常糟糕的做法;参见 Don't Read Lines With For。如果你想使用 for 循环,用它来遍历 files 而不是:

    for f in *.dat; do
      # handle case where no files exist
      [[ -e "$f" ]] || continue 
      # read each given file
      while read -r line; do
        if [[ $line = *""* ]]; then
          echo " present in $line in file $f"
        else
          echo " not present in $line in file $f"
        fi
      done <"$f"
    done