读取一个文件,members_08_14.csv
只包含一个数字列表,while循环正在读取每一行。对于每一行,该数字与正则表达式匹配,以确保它只是数字和正好11个字符。
while read card
do
if [[ $card =~ ^[0-9]{11}$ ]]
then
echo "some sql statement with $card" >> temp.sql;
else
echo "Invalid card number in file: $card";
fi
done <registered/members_08_14.csv
有趣的是,如果正则表达式不匹配,则不会执行else。我希望将该行写入temp.sql
,或者将一行打印到stdout
,表示该卡号无效。
然而,行为更像是true
条件或仅为整个文件激活false
条件。为什么会这样?
以下是已注册/ members_08_14.csv的内容:
47678009583
47678009585
47678009587
47678009590
476780095905
第一行有效,第5行无效。
cat -vte registered/members_08_14.csv
47678009583$
47678009585$
47678009587$
47678009590$
476780095905$
答案 0 :(得分:3)
如果文件的最后一行末尾没有换行符,read
会将其内容放入card
- 但会以非零值退出。因为在这种情况下read
已退出非零值,所以while
循环将退出而不会继续运行正则表达式的语句。
最简单的解决方法是更正文件。
您可以采取的另一种方法是忽略read
实际填充其目标时的退出状态(并在此时将$'\r'
放入IFS,以便read
将忽略DOS换行符中的额外字符):
while card=; IFS=$' \t\r\n' read -r card || [[ $card ]]; do
if [[ $card =~ ^[0-9]{11}$ ]]
then
echo "some sql statement with $card" >> temp.sql;
else
echo "Invalid card number in file: $card";
fi
done <registered/members_08_14.csv
答案 1 :(得分:2)
也许你的文件是DOS格式,你也可以在变量的末尾读取回车符(\r
)。尝试运行dos2unix file
或sed -i 's|\r||' file
。另一种方法是在每次输入后通过此
while IFS=$' \t\r\n' read -r card