목록을 기반으로 .xls / .xlsx 스프레드 시트를 여러 .csv로 변환


10

단일 .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

답변:


10

다른 루프 안에 루프를 넣을 수 있습니다.

오류를 피하려면 결과 for와 함께 사용하지 마십시오 find.

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

7

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 % 작동하지 않는 것 같습니다. 그러나 시도해 볼 가치가 있으며 이것이 향후 버전에서 아마도 해당 옵션이있는 첫 번째 버전이므로 구현이 더 좋고 쉽습니다.


0

사용 Gnumeric:

ssconvert -S filename.xlsx filename.csv

csv시트 당 하나의 파일 을 가져옵니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.