首页 > 解决方案 > Bash 计算循环中文件和行的总数

问题描述

我正在尝试计算执行脚本的目录中每个 .xls 的文件和行数。

total_files=0
total_lines=0

find . -type f -name "*.xls" | while read FILE; do

 count=$(grep -c ^ < "$FILE") #get number of lines in particular file
 total_lines=$(($total_lines+$count));
 ((total_files++))

done

echo "Total files: $total_files"
echo "Total lines: $total_lines"

但我每次只得到0。

我知道这可能是因为 while 循环是在子 shell 中执行的,但使用<<<在当前 shell 中执行不会有帮助:

done <<< "$(find . -type f -name "*.xls")"

标签: linuxbashawksed

解决方案


Unix 行计数方法严格适用于 TEXT 文件,包括(大部分)csv 文件。

Excel 文件不是文本。 Excel 文件要么是.xls2007 年以前使用的二进制文件类型,要么是.xlsx从那时起使用的开放 xml 样式文件。两者都不是面向线的。

唯一可靠的方法是使用可以解析 Excel 文件并且可以遍历文件树的脚本语言。

Python、RubyPerl都可以在 Unix 上做到这一点。

这是一个带有 Pandas 的 Python,用于遍历文件树、读取文件并计算该文件默认工作表的行数:

# Note: You may need to use pip to install
#       pandas
#       xldd
#       openpyxl

import pandas as pd
from pathlib import Path 

p=Path('ur_root_path')

file_count=0
line_count=0
for pn in p.glob('**/*.xls*'):
    try:
        df=pd.read_excel(pn,header=None)
        print(f'{pn}\n{df}')
        file_count+=1
        line_count+=df.shape[0]
    except ValueError as e:
        print(f'{pn}: {e}')
    
print(f'files={file_count}, total lines={line_count}')  

鉴于此文件夹:

$ ls -1 /tmp/test
Book1.xlsx          # 3 rows in col 'A' -- 1-3
Book2.xls           # 6 rows in col 'C' -- 1-6

运行该脚本会产生:

/tmp/test/Book2.xls
    0   1  2
0 NaN NaN  1
1 NaN NaN  2
2 NaN NaN  3
3 NaN NaN  4
4 NaN NaN  5
5 NaN NaN  6
/tmp/test/Book1.xlsx
   0
0  1
1  2
2  3
files=2, total lines=9

推荐阅读