根据列表将.xls / .xlsx电子表格转换为多个.csv


9

我需要将单个.xls / .xlsx文件的所有工作表都转换为.csv。这将在所有目录和子目录中的所有.xls文件上进行(递归)。

步骤1:使用以下命令将所有.xls的工作表名称转换为.csv:

for file in $(find . -name '*.xls' -o -name '*.xlsx');do in2csv -n "$file" > ${file%.xls}-sheetnames-list.csv; done

filename-sheetnames-list.csv 可以作为列表:

sheetname1
sheetname2
sheetname3

步骤2:使用in2csv将特定工作表转换为.csv的代码是:

in2csv --sheet "SHEETNAME" filename.xls > filename-SHEETNAME.csv

如何获得.xls / x中的每个工作表名称,并为包含.xls / x的所有目录分别编写每个工作表?

in2csv --write-sheets "-" filename.xls > filename-sheet1.csv filename-sheet2.csv .... 仅在sheet1.csv上提供输出,不确定如何从中获取所有表。


2
为什么不只使用find每个.xls{,x}而循环使用每个工作表-exec
甜点,

1
@glennjackman这是Unix和Linux上的最佳话题。
terdon

Answers:


10

您可以将一个循环放在另一个循环中。

为避免错误,请勿将其forfind结果一起使用。

while IFS= read -r file; do
    while IFS= read -r sheet; do
        in2csv --sheet "$sheet" "$file" > "${file%.*}-${sheet}.csv"
    done < <(in2csv -n "$file")
done < <(find . -name '*.xls' -o -name '*.xlsx')

@muru啊废话。你是绝对正确的。我在一个已经更改了IFS的环境中进行了测试,因此它当然会向下传播。白痴。谢谢,修改已还原。
terdon

@RoVo第一个选项工作正常。但是第二个没有任何输出或错误。我不确定为什么;单.xls in2csv --write-sheets "-" filename.xls > sheetname.csv只给第一张。我不知道要添加什么其他信息来编写所有工作表。这将为我们提供更正您的代码的线索。
csheth

1
您是否已更新到该版本1.0.2?pip install csvkit -U。我认为它的工作方式是不是你喜欢的,从第一个选项简单skript你有更多的方式来控制输出和文件名等
pLumo

仍然无法使用更新,是的,我宁愿使用列表,而不是使用列表,--write-sheets 也许您可以将此替代选项设置为另一个答案...然后,我将接受第一个选项作为答案。谢谢@RoVo
csheth

1
通常在另一个答案中有其他选择也许是个好主意。谢谢,很高兴能为您提供帮助。
pLumo

6

跳过查找并使用bash:

shopt -s globstar  # enable recursive globbing
for f in **/*.xls{,x}  # for files ending in .xls or .xlsx
do
    in2csv -n "$f" |   # get the sheetnames
      xargs -I {} bash -c 'in2csv --sheet "$2" "$1" > "${1%.*}"-"$2".csv' _ "$f" {} # {} will be replaced with the sheetname
done

该脚本看起来很优雅,但是其输出不filename-{}.csv包含任何数据。我是新手,似乎无法通过编辑脚本和阅读来查找错误。一些帮助?
csheth

@ChintanSheth我不好,我忘了重定向将在外面xargs。已更正,现在不那么优雅。
muru

xargs并且>是邪恶:-P。这就是为什么我更喜欢另一个循环,它不容易出错。
pLumo

@RoVo我通常也会去另一个循环,只是想在这里显示另一个方法。
muru

现在可以使用,但是比@RoVo回答要慢一些。
csheth

3

csvkit版本> 1.0.2具有内置功能来写入所有工作表:

--write-sheets: WRITE_SHEETS
                      The names of the Excel sheets to write to files, or
                      "-" to write all sheets.

因此,您可以尝试以下操作:

find . -name '*.xls' -o -name '*.xlsx' -exec in2csv --write-sheets "-" {} \;

注意:

这似乎无法按预期100%工作。但是值得一试,因为这是带有该选项的第一个版本,也许在将来的版本中,实现会更好/更轻松。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.