for i in $( find . -name 'x.txt' ); do; if [ grep 'vvvv' ];
then; grep 'vvvv' -A 2 $i | grep -v vvvv | grep -v '-' >> y.csv; else
grep 0 $i >> y.csv; fi; done
这可能有什么问题?
谢谢!
答案 0 :(得分:2)
;
之后不允许do
。
那就是说,你可能想要的更像是:
while IFS= read -r -d '' i; do
if grep -q -e vvvv -- "$i"; then
grep -e 'vvvv' -A 2 -- "$i" | egrep -v -e '(vvvv|-)'
else
grep 0 -- "$i"
fi
done < <(find . -name 'x.txt' -print0) >y.csv
注意:
find -print0
和IFS= read -r -d ''
可确保正确处理所有可能的文件名(包括包含空格,换行符等的文件名)。有关此成语的更多背景信息,请参阅BashFAQ #1。if grep ...
检查if
的输出,则应使用grep
。使其成为if [ grep ... ]
意味着您将grep
作为参数传递给test
命令,而不是将其作为命令本身运行。y.csv
一次,而不是一遍又一遍地重新打开文件,只写一行(或短行数)并关闭它。--
将选项与位置参数分开。-
作为要搜索的字符串传递给grep
时,应该以{{1}}开头。也就是说,在目前的情况下,我们可以结合两个-e
调用,完全避免需要。grep -v
,而不是"$i"
。否则,这些值将在空格上拆分,并且生成的每个部分都将单独计算为glob,从而无法正确处理由这些操作中的任何一个修改的文件名。