我需要扫描文件的每一行,查找hex \ x7E以上的任何字符。该文件有几百万行,因此提高效率会很好。到目前为止,读取while循环中的每一行,这样可以找到包含无效字符的行:
echo "$line" | grep -P "[\x7F-\xFF]" > /dev/null 2>&1
if [ $? -eq 0 ]; then...
但这不是:
if [[ "$line" =~ [\x7F-\xFF] ]]; then...
我认为第二种方式会更高效,如果我可以让它发挥作用。我错过了什么?
答案 0 :(得分:4)
如果你对效率感兴趣,你不应该用bash写你的循环。您应该根据管道重新考虑您的程序并使用有效的工具。
那就是说,你可以用
来做到这一点LC_CTYPE=C LC_COLLATE=C
if [[ "$line" =~ [$'\x7f'-$'\xff'] ]]
then
echo "It contains bytes \x7F or up"
fi
答案 1 :(得分:1)
我基本上必须拆分文件。有效记录转到一个文件,无效记录转到另一个文件。
sed -n '/[^\x0-\x7e]/w badrecords
//! w goodrecords'
答案 2 :(得分:0)
如果您已经在使用Perl正则表达式,那么您也可以使用perl来完成任务:
perl -ne '
if (/[\x7F-\xFF]/) {print STDERR $_} else {print}
' file > valid 2> invalid
我敢打赌,这比bash循环更快。
我怀疑这会更有效率,即使它处理文件两次:
grep -P "[\x7F-\xFF]" file > invalid
grep -vP "[\x7F-\xFF]" file > valid
您想将您的grep代码编写为
if grep -qP "[\x7F-\xFF]" <<< "$line"; then...