使用 "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
我写了一个 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