リストに基づいて.xls / .xlsxスプレッドシートを複数の.csvに変換する


9

1つの.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 2017年

回答:


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 2017年

@RoVo最初のオプションは正常に動作します。ただし、2つ目では出力やエラーは発生しません。なぜだかわかりません。シングルの.xls in2csv --write-sheets "-" filename.xls > sheetname.csv場合、最初のシートのみが表示されます。すべてのシートを書き込むために追加する追加情報がわかりません。これにより、コードを修正する手がかりが得られます。
csheth 2017年

1
そのバージョン1.0.2に更新しましたか?pip install csvkit -U。私はそれが機能する方法はあなたが好きではないと思います、最初のオプションからの単純なskriptであなたは出力やファイル名などを制御するより多くの方法があります
pLumo

それでも更新では機能しません。そうです、私はリストよりも--write-sheets このオプションを使用したいのですが、この代替オプションを別の回答として設定できます...最初のオプションを回答として受け入れます。ありがとう@RoVo
csheth

1
おそらく一般的に、別の答えで代替オプションを用意するのは良い考えです。よろしくお願いいたします。
pLumo 2017年

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 2017年

@ChintanSheth私の悪い、私はリダイレクトが外になることを忘れていましたxargs。修正されましたが、今ほどエレガントではありません。
muru

xargsそして>悪です:-P。それが私が別のループを好む理由です、それはエラーが起こりにくいです。
pLumo

@RoVo私は通常、別のループにも行きましたが、ここに別のメソッドを示したかっただけです。
muru

これは現在機能しますが、@ RoVoの回答よりも少し遅くなります。
csheth 2017年

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%動作しないようです。しかし、試してみる価値はあります。これはそのオプションを備えた最初のバージョンであるため、おそらく将来のバージョンでは、実装がより簡単になります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.