我有一个while循环,简化如下:
while read -r line
do
(delete some lines from file2.txt)
done < file.txt
如果file2.txt
为空,那么这个while循环就不再需要运行了。
换句话说,我需要这个:
while read -r line AND file2.txt IS NOT EMPTY
do
(delete some lines from file2.txt
done < file.txt
我尝试过将while read -r line
与-s file2.txt
组合,但结果不起作用:
while [ read -r line ] || [ -s file2.txt ]
do
(delete some lines from file2.txt)
done < file.txt
如何使用while循环读取文件中的行,同时检查另一个文件是否为空?
将读取和测试组合为:
while read -r line && [ -s file2.txt ]
do
# (delete some lines from file2.txt)
echo "$line"
done <file.txt
这将在循环的每次迭代之前检查file2.txt
是否为非空。
无用地使用cat会简化这里的事情:
while read -r line
do
(delete some lines from file2.txt)
done < <(test -s file2.txt && cat file.txt)
$ cat file.txt
foo
bar
baz
$ cat file2.txt
something
$ while read -r line; do echo "$line"; done < <(test -s file2.txt && cat file.txt)
foo
bar
baz
$ > file2.txt
$ while read -r line; do echo "$line"; done < <(test -s file2.txt && cat file.txt)
$
您可以执行以下操作:
while read -r lf1 && [[ -s "path/to/file2" ]] && read -r lf2 <&3; do
echo "$lf1"; echo "$lf2"
done <file1 3<file2
只是一个示例,您可以在while
块中添加自己的代码。
测试:
<~/Temp>$ cat file1
line from file1
line2 from file1
<~/Temp>$ cat file2
I am not empty
Yep not empty
<~/Temp>$ while read -r lf1 && [[ -s "/Volumes/Data/jaypalsingh/Temp/file2" ]] && read -r lf2 <&3; do echo "$lf1"; echo "$lf2"; done <file1 3<file2
line from file1
I am not empty
line2 from file1
Yep not empty
<~/Temp>$ >file2
<~/Temp>$ while read -r lf1 && [[ -s "/Volumes/Data/jaypalsingh/Temp/file2" ]] && read -r lf2 <&3; do echo "$lf1"; echo "$lf2"; done <file1 3<file2
<~/Temp>$
就我个人而言,我只会做
while read -r line
do
[ ! -s file2.txt ] && break
# (delete some lines from file2.txt)
done <file.txt
严格来说,我的解决方案与其他任何解决方案都没有什么不同或更好的地方,但这是个人品味的问题。我不喜欢在其他条件下混合一个循环,它做的事情就像从文件中读取行一样简单。我发现这会降低代码的可读性。毫无疑问,其他人会不同意,甚至可能认为在循环中依赖break
是一种糟糕的做法,但我发现它可以让我快速掌握正在发生的事情,而不必放慢速度,在心理上处理有条件的事情,就像你在外周视觉中看到停车标志时停下来一样,而不必直接看标志并阅读字母"STOP"就能理解它。像while read -r line
这样的东西是如此常见的习语,它们本质上相当于普通路标的编程。你可以立即识别它们,而不必在脑海中解析它们。不管怎样,就像我说的,这只是我个人的看法。你可以不同意。
只是对Joe 给出的答案进行了一点优化
while [ -s file2.txt ] && read -r line
do
# (delete some lines from file2.txt)
done <file.txt