Chuyển đổi bảng tính .xls / .xlsx thành nhiều .csv dựa trên danh sách


9

Tôi cần chuyển đổi tất cả các trang tính của một tệp .xls / .xlsx thành một tệp .csv. Điều này sẽ được thực hiện trên tất cả các tệp .xls trong tất cả các thư mục và thư mục con (đệ quy).

Bước 1 : Nhận tên trang tính của tất cả .xls vào .csv bằng cách sử dụng:

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

filename-sheetnames-list.csv có thể hoạt động như một danh sách:

sheetname1
sheetname2
sheetname3

Bước 2 : Mã để chuyển đổi một trang cụ thể thành .csv bằng cách sử dụng in2csv là:

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

Làm cách nào tôi có thể nhận được mọi tên trang tính trong .xls / x và viết riêng từng trang tính cho tất cả các thư mục chứa .xls / x?

in2csv --write-sheets "-" filename.xls > filename-sheet1.csv filename-sheet2.csv .... chỉ cung cấp đầu ra trên sheet1.csv, không biết làm thế nào để có được tất cả các trang tính từ đây.


2
Tại sao không chỉ findmỗi .xls{,x}và vòng lặp trên mỗi tờ bằng cách sử dụng -exec?
tráng miệng

1
@glennjackman đây là chủ đề hoàn hảo ở đây, giống như trên Unix & Linux .
terdon

Câu trả lời:


10

Bạn chỉ có thể đặt một vòng lặp bên trong một vòng lặp khác.

Để tránh lỗi, không sử dụng forvới findkết quả.

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 ah tào lao. Bạn hoàn toàn đúng. Tôi đã thử nghiệm trong một môi trường mà IFS đã bị thay đổi nên dĩ nhiên nó đã lan truyền xuống dưới. Đồ ngốc . Cảm ơn, chỉnh sửa hoàn nguyên.
terdon

@RoVo tùy chọn đầu tiên hoạt động tốt. Cái thứ hai tuy nhiên không cho tôi đầu ra hay lỗi. Tôi không chắc tại sao; cho một .xls in2csv --write-sheets "-" filename.xls > sheetname.csvchỉ cung cấp cho tờ đầu tiên. Tôi không biết thêm thông tin nào để thêm vào để viết tất cả các tờ. Điều đó sẽ cho chúng tôi manh mối để sửa mã của bạn.
csheth

1
Bạn đã cập nhật lên phiên bản 1.0.2 đó chưa? pip install csvkit -U. Tôi nghĩ rằng cách nó hoạt động không phải là những gì bạn thích, với skript đơn giản từ tùy chọn thứ 1, bạn có nhiều cách hơn để kiểm soát đầu ra và tên tệp, v.v.
pLumo

vẫn không hoạt động với bản cập nhật và có, tôi thích sử dụng danh sách hơn --write-sheets Có lẽ bạn có thể đặt tùy chọn thay thế này làm câu trả lời khác ... Tôi sẽ chấp nhận tùy chọn đầu tiên làm câu trả lời sau đó. Cảm ơn @RoVo
csheth

1
Có lẽ nói chung là một ý tưởng tốt để có các lựa chọn thay thế trong một câu trả lời khác. Cảm ơn, rất vui vì tôi có thể giúp đỡ.
pLumo

6

Bỏ qua tìm và sử dụng 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

kịch bản này trông thanh lịch nhưng đầu ra của nó filename-{}.csvkhông chứa dữ liệu. Tôi là người mới và dường như không thể tìm thấy lỗi bằng cách chỉnh sửa tập lệnh và đọc lên. Một số trợ giúp?
csheth

@ChintanSheth xấu của tôi, tôi đã quên chuyển hướng sẽ ở bên ngoài xargs. Sửa chữa, không thanh lịch như bây giờ.
muru

xargs>là xấu xa :-P. Đó là lý do tại sao tôi thích một vòng lặp khác, nó ít bị lỗi hơn.
pLumo

@RoVo Tôi cũng thường đi một vòng lặp khác, chỉ muốn hiển thị một phương thức khác ở đây.
muru

Điều này hoạt động ngay bây giờ, tuy nhiên hơi chậm hơn câu trả lời @RoVo.
csheth

3

phiên bản csvkit> 1.0.2 có chức năng dựng sẵn để ghi tất cả các trang tính:

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

Vì vậy, bạn có thể thử như sau:

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

Ghi chú:

Điều này dường như không hoạt động 100% như mong đợi. Nhưng đáng để thử và vì đây là phiên bản đầu tiên với tùy chọn đó có thể trong các phiên bản trong tương lai, việc triển khai sẽ tốt hơn / dễ dàng hơn.


0

Sử dụng Gnumeric:

ssconvert -S filename.xlsx filename.csv

để có được một csvtập tin trên mỗi tờ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.