第26回シェル芸勉強会に参加してきました(復習)
Pocket

2016年12月25日、一応世間ではクリスマスなのだが、新宿でシェル芸勉強会があったので行ってきた。
で、その復習。

今回はエクシェル芸…というより、Excelに限らずMSオフィスのファイルをbash上でいろいろといじるという内容。
問題及び模範解答はこちら。最初に、問題に利用するファイルをgitで落としておくといいだろう。

git clone https://github.com/ryuichiueda/ShellGeiData.git

 

Q1.

.xlsxや.docx、.pptxはzipファイルになっており、xlsなどのようにバイナリ形式のデータにはなっていない。
このため、unzipで展開してから再度zip化してやることで、また開けることを確認しようという問題。問題というか、ファイルの構造を理解するのが主となっている。

とりあえず、xlsxファイルについて展開してみよう。
大体、こんな感じの構造になっている。ファイル名から、どのファイルがSheetに当たるのかは推測が立つだろう。 Excelの各シートはxmlで定義されているという事がわかる。

blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -od hanshin hanshin.xlsx 
Archive:  hanshin.xlsx
  inflating: hanshin/[Content_Types].xml  
  inflating: hanshin/_rels/.rels     
  inflating: hanshin/xl/_rels/workbook.xml.rels  
  inflating: hanshin/xl/workbook.xml  
  inflating: hanshin/xl/sharedStrings.xml  
  inflating: hanshin/xl/theme/theme1.xml  
  inflating: hanshin/xl/styles.xml   
  inflating: hanshin/xl/worksheets/sheet1.xml  
 extracting: hanshin/docProps/thumbnail.jpeg  
  inflating: hanshin/docProps/core.xml  
  inflating: hanshin/docProps/app.xml  
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ tree hanshin
hanshin
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   ├── core.xml
│   └── thumbnail.jpeg
└── xl
    ├── _rels
    │   └── workbook.xml.rels
    ├── sharedStrings.xml
    ├── styles.xml
    ├── theme
    │   └── theme1.xml
    ├── workbook.xml
    └── worksheets
        └── sheet1.xml

6 directories, 10 files

 

同様に、docx・pptxファイルについても展開してみる。

20141019OSC_LT.pptx  certificate.docx     graph.xlsx           hanshin/             hanshin.xlsx         template.pptx
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -od certificate{,.docx}
Archive:  certificate.docx
  inflating: certificate/[Content_Types].xml  
  inflating: certificate/_rels/.rels  
  inflating: certificate/word/_rels/document.xml.rels  
  inflating: certificate/word/document.xml  
  inflating: certificate/word/footnotes.xml  
  inflating: certificate/word/endnotes.xml  
  inflating: certificate/word/header1.xml  
  inflating: certificate/word/_rels/header1.xml.rels  
  inflating: certificate/word/theme/theme1.xml  
 extracting: certificate/docProps/thumbnail.jpeg  
 extracting: certificate/word/media/image1.png  
  inflating: certificate/word/_rels/settings.xml.rels  
  inflating: certificate/word/settings.xml  
  inflating: certificate/word/stylesWithEffects.xml  
  inflating: certificate/word/webSettings.xml  
  inflating: certificate/word/styles.xml  
  inflating: certificate/docProps/app.xml  
  inflating: certificate/docProps/core.xml  
  inflating: certificate/word/fontTable.xml  
  inflating: certificate/docProps/custom.xml  
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ tree certificate
certificate
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   ├── core.xml
│   ├── custom.xml
│   └── thumbnail.jpeg
└── word
    ├── _rels
    │   ├── document.xml.rels
    │   ├── header1.xml.rels
    │   └── settings.xml.rels
    ├── document.xml
    ├── endnotes.xml
    ├── fontTable.xml
    ├── footnotes.xml
    ├── header1.xml
    ├── media
    │   └── image1.png
    ├── settings.xml
    ├── styles.xml
    ├── stylesWithEffects.xml
    ├── theme
    │   └── theme1.xml
    └── webSettings.xml

6 directories, 19 files
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -od 20141019OSC_LT{,.pptx}
Archive:  20141019OSC_LT.pptx
  inflating: 20141019OSC_LT/[Content_Types].xml  
  inflating: 20141019OSC_LT/_rels/.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide10.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide11.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide12.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide14.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide9.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide15.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide16.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide13.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide8.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide7.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide1.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide2.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide3.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide4.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide5.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide6.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide17.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide18.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide19.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide29.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide30.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide31.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide32.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide33.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide34.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide28.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide27.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide26.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide20.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide21.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide22.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide23.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide24.xml.rels  
  inflating: 20141019OSC_LT/ppt/slides/_rels/slide25.xml.rels  
  inflating: 20141019OSC_LT/ppt/_rels/presentation.xml.rels  
  inflating: 20141019OSC_LT/ppt/presentation.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide25.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide21.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide20.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide19.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide18.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide17.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide16.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide15.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide14.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide13.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide22.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide23.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide34.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide26.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide27.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide28.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide29.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide30.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide31.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide32.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide33.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide12.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide11.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide10.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide1.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide2.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide3.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide4.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide24.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide6.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide9.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide5.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide7.xml  
  inflating: 20141019OSC_LT/ppt/slides/slide8.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout2.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout9.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout10.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout11.xml.rels  
  inflating: 20141019OSC_LT/ppt/notesSlides/_rels/notesSlide1.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout8.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout7.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout6.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout5.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout4.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout3.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/_rels/slideLayout1.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideMasters/slideMaster1.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout1.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout8.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout9.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout10.xml  
  inflating: 20141019OSC_LT/ppt/slideMasters/_rels/slideMaster1.xml.rels  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout7.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout6.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout5.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout4.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout3.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout2.xml  
  inflating: 20141019OSC_LT/ppt/notesSlides/notesSlide1.xml  
  inflating: 20141019OSC_LT/ppt/slideLayouts/slideLayout11.xml  
 extracting: 20141019OSC_LT/ppt/media/image2.gif  
  inflating: 20141019OSC_LT/ppt/handoutMasters/_rels/handoutMaster1.xml.rels  
 extracting: 20141019OSC_LT/ppt/media/image3.png  
 extracting: 20141019OSC_LT/ppt/media/image10.jpg  
 extracting: 20141019OSC_LT/docProps/thumbnail.jpeg  
  inflating: 20141019OSC_LT/ppt/handoutMasters/handoutMaster1.xml  
  inflating: 20141019OSC_LT/ppt/notesMasters/notesMaster1.xml  
  inflating: 20141019OSC_LT/ppt/theme/theme1.xml  
  inflating: 20141019OSC_LT/ppt/notesMasters/_rels/notesMaster1.xml.rels  
 extracting: 20141019OSC_LT/ppt/media/image9.jpg  
 extracting: 20141019OSC_LT/ppt/media/image7.png  
 extracting: 20141019OSC_LT/ppt/media/image1.png  
 extracting: 20141019OSC_LT/ppt/media/image4.png  
 extracting: 20141019OSC_LT/ppt/media/image8.jpg  
  inflating: 20141019OSC_LT/ppt/theme/theme3.xml  
  inflating: 20141019OSC_LT/ppt/theme/theme2.xml  
 extracting: 20141019OSC_LT/ppt/media/image5.png  
 extracting: 20141019OSC_LT/ppt/media/image6.gif  
  inflating: 20141019OSC_LT/ppt/viewProps.xml  
  inflating: 20141019OSC_LT/ppt/tableStyles.xml  
  inflating: 20141019OSC_LT/ppt/presProps.xml  
  inflating: 20141019OSC_LT/docProps/app.xml  
  inflating: 20141019OSC_LT/docProps/core.xml  
  inflating: 20141019OSC_LT/ppt/printerSettings/printerSettings1.bin  
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ tree 20141019OSC_LT
20141019OSC_LT
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   ├── core.xml
│   └── thumbnail.jpeg
└── ppt
    ├── _rels
    │   └── presentation.xml.rels
    ├── handoutMasters
    │   ├── _rels
    │   │   └── handoutMaster1.xml.rels
    │   └── handoutMaster1.xml
    ├── media
    │   ├── image1.png
    │   ├── image10.jpg
    │   ├── image2.gif
    │   ├── image3.png
    │   ├── image4.png
    │   ├── image5.png
    │   ├── image6.gif
    │   ├── image7.png
    │   ├── image8.jpg
    │   └── image9.jpg
    ├── notesMasters
    │   ├── _rels
    │   │   └── notesMaster1.xml.rels
    │   └── notesMaster1.xml
    ├── notesSlides
    │   ├── _rels
    │   │   └── notesSlide1.xml.rels
    │   └── notesSlide1.xml
    ├── presProps.xml
    ├── presentation.xml
    ├── printerSettings
    │   └── printerSettings1.bin
    ├── slideLayouts
    │   ├── _rels
    │   │   ├── slideLayout1.xml.rels
    │   │   ├── slideLayout10.xml.rels
    │   │   ├── slideLayout11.xml.rels
    │   │   ├── slideLayout2.xml.rels
    │   │   ├── slideLayout3.xml.rels
    │   │   ├── slideLayout4.xml.rels
    │   │   ├── slideLayout5.xml.rels
    │   │   ├── slideLayout6.xml.rels
    │   │   ├── slideLayout7.xml.rels
    │   │   ├── slideLayout8.xml.rels
    │   │   └── slideLayout9.xml.rels
    │   ├── slideLayout1.xml
    │   ├── slideLayout10.xml
    │   ├── slideLayout11.xml
    │   ├── slideLayout2.xml
    │   ├── slideLayout3.xml
    │   ├── slideLayout4.xml
    │   ├── slideLayout5.xml
    │   ├── slideLayout6.xml
    │   ├── slideLayout7.xml
    │   ├── slideLayout8.xml
    │   └── slideLayout9.xml
    ├── slideMasters
    │   ├── _rels
    │   │   └── slideMaster1.xml.rels
    │   └── slideMaster1.xml
    ├── slides
    │   ├── _rels
    │   │   ├── slide1.xml.rels
    │   │   ├── slide10.xml.rels
    │   │   ├── slide11.xml.rels
    │   │   ├── slide12.xml.rels
    │   │   ├── slide13.xml.rels
    │   │   ├── slide14.xml.rels
    │   │   ├── slide15.xml.rels
    │   │   ├── slide16.xml.rels
    │   │   ├── slide17.xml.rels
    │   │   ├── slide18.xml.rels
    │   │   ├── slide19.xml.rels
    │   │   ├── slide2.xml.rels
    │   │   ├── slide20.xml.rels
    │   │   ├── slide21.xml.rels
    │   │   ├── slide22.xml.rels
    │   │   ├── slide23.xml.rels
    │   │   ├── slide24.xml.rels
    │   │   ├── slide25.xml.rels
    │   │   ├── slide26.xml.rels
    │   │   ├── slide27.xml.rels
    │   │   ├── slide28.xml.rels
    │   │   ├── slide29.xml.rels
    │   │   ├── slide3.xml.rels
    │   │   ├── slide30.xml.rels
    │   │   ├── slide31.xml.rels
    │   │   ├── slide32.xml.rels
    │   │   ├── slide33.xml.rels
    │   │   ├── slide34.xml.rels
    │   │   ├── slide4.xml.rels
    │   │   ├── slide5.xml.rels
    │   │   ├── slide6.xml.rels
    │   │   ├── slide7.xml.rels
    │   │   ├── slide8.xml.rels
    │   │   └── slide9.xml.rels
    │   ├── slide1.xml
    │   ├── slide10.xml
    │   ├── slide11.xml
    │   ├── slide12.xml
    │   ├── slide13.xml
    │   ├── slide14.xml
    │   ├── slide15.xml
    │   ├── slide16.xml
    │   ├── slide17.xml
    │   ├── slide18.xml
    │   ├── slide19.xml
    │   ├── slide2.xml
    │   ├── slide20.xml
    │   ├── slide21.xml
    │   ├── slide22.xml
    │   ├── slide23.xml
    │   ├── slide24.xml
    │   ├── slide25.xml
    │   ├── slide26.xml
    │   ├── slide27.xml
    │   ├── slide28.xml
    │   ├── slide29.xml
    │   ├── slide3.xml
    │   ├── slide30.xml
    │   ├── slide31.xml
    │   ├── slide32.xml
    │   ├── slide33.xml
    │   ├── slide34.xml
    │   ├── slide4.xml
    │   ├── slide5.xml
    │   ├── slide6.xml
    │   ├── slide7.xml
    │   ├── slide8.xml
    │   └── slide9.xml
    ├── tableStyles.xml
    ├── theme
    │   ├── theme1.xml
    │   ├── theme2.xml
    │   └── theme3.xml
    └── viewProps.xml

19 directories, 121 files

あとは、またzip化して開けることを確認してやれば良い。
この一連の処理をワンラインで記述する場合、以下のようになる。

ls -1 *x | awk -F. '{cmd="unzip -d "$1" "$0 ";(cd "$1";zip -r ../"$1"_2."$2" ./)";system(cmd)}'
Sponsored Links

Q2.

「20141019OSC_LT.pptx」ファイルで、何度「危険」というキーワードが出てくるかを計算する。
とりあえず、以下の内容で回答した。


unzip -p 20141019OSC_LT.pptx ppt/slides/slide*.xml | grep -o 危険 | wc -l

 

一応、補足説明を入れておくと、unzipでは以下のようにzipファイル内で展開するファイルを指定することができる(ワイルドカード指定可能。(複数指定できるので)ブレース展開での指定可能)。
で、PowerPointの各スライドの内容だけを取得することが目的なので、「ppt/slides/」配下にあるslideXX.xmlファイルのみを取得している。
また、「-p」オプションで展開した内容を標準出力で出力できるので、それをそのままgrepに渡してやり数を数えている。このとき、-cでカウントすると同じ行に複数目当ての単語がある場合1個としてカウントされてしまうので注意。

ちなみに、unzipでは「-l」でzipファイルの中身を確認できるので、先にそれで展開するファイルの推測を立てるといいだろう。

unzip -l zipファイル

blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -l certificate.docx
Archive:  certificate.docx
  Length      Date    Time    Name
---------  ---------- -----   ----
     2041  1980-01-01 00:00   [Content_Types].xml
      882  1980-01-01 00:00   _rels/.rels
     1345  1980-01-01 00:00   word/_rels/document.xml.rels
    43370  1980-01-01 00:00   word/document.xml
     1635  1980-01-01 00:00   word/footnotes.xml
     1629  1980-01-01 00:00   word/endnotes.xml
     4729  1980-01-01 00:00   word/header1.xml
      289  1980-01-01 00:00   word/_rels/header1.xml.rels
     7643  1980-01-01 00:00   word/theme/theme1.xml
    45844  1980-01-01 00:00   docProps/thumbnail.jpeg
   149691  1980-01-01 00:00   word/media/image1.png
      460  1980-01-01 00:00   word/_rels/settings.xml.rels
     3811  1980-01-01 00:00   word/settings.xml
     9472  1980-01-01 00:00   word/stylesWithEffects.xml
      431  1980-01-01 00:00   word/webSettings.xml
     8606  1980-01-01 00:00   word/styles.xml
     1043  1980-01-01 00:00   docProps/app.xml
      754  1980-01-01 00:00   docProps/core.xml
     1742  1980-01-01 00:00   word/fontTable.xml
      353  1980-01-01 00:00   docProps/custom.xml
---------                     -------
   285770                     20 files

 

Q3.

「20141019OSC_LT.pptx」ファイルにある画像ファイルのみを抽出し別ディレクトリに移動、zip化してやろうという問題。
以下の内容で回答している。

unzip -d ./pic 20141019OSC_LT.pptx *{png,gif,jpeg,jpg};zip -r pic.zip ./pic
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -od ./pic 20141019OSC_LT.pptx *{png,gif,jpeg,jpg};zip -r pic.zip ./pic
Archive:  20141019OSC_LT.pptx
 extracting: ./pic/ppt/media/image2.gif
 extracting: ./pic/ppt/media/image3.png
 extracting: ./pic/ppt/media/image10.jpg
 extracting: ./pic/docProps/thumbnail.jpeg
 extracting: ./pic/ppt/media/image9.jpg
 extracting: ./pic/ppt/media/image7.png
 extracting: ./pic/ppt/media/image1.png
 extracting: ./pic/ppt/media/image4.png
 extracting: ./pic/ppt/media/image8.jpg
 extracting: ./pic/ppt/media/image5.png
 extracting: ./pic/ppt/media/image6.gif
updating: pic/ (stored 0%)
updating: pic/docProps/ (stored 0%)
updating: pic/docProps/thumbnail.jpeg (deflated 22%)
updating: pic/ppt/ (stored 0%)
updating: pic/ppt/media/ (stored 0%)
updating: pic/ppt/media/image6.gif (deflated 0%)
updating: pic/ppt/media/image8.jpg (deflated 7%)
updating: pic/ppt/media/image3.png (deflated 1%)
updating: pic/ppt/media/image7.png (deflated 10%)
updating: pic/ppt/media/image2.gif (deflated 1%)
updating: pic/ppt/media/image9.jpg (deflated 12%)
updating: pic/ppt/media/image5.png (deflated 13%)
updating: pic/ppt/media/image4.png (deflated 4%)
updating: pic/ppt/media/image10.jpg (deflated 6%)
updating: pic/ppt/media/image1.png (deflated 4%)
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -l pic.zip
Archive:  pic.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-12-26 12:05   pic/
        0  2016-12-26 12:07   pic/docProps/
    11732  1980-01-01 00:00   pic/docProps/thumbnail.jpeg
        0  2016-12-26 12:05   pic/ppt/
        0  2016-12-26 12:07   pic/ppt/media/
    67739  1980-01-01 00:00   pic/ppt/media/image6.gif
    95304  1980-01-01 00:00   pic/ppt/media/image8.jpg
    13744  1980-01-01 00:00   pic/ppt/media/image3.png
   159302  1980-01-01 00:00   pic/ppt/media/image7.png
    99260  1980-01-01 00:00   pic/ppt/media/image2.gif
   379635  1980-01-01 00:00   pic/ppt/media/image9.jpg
    70496  1980-01-01 00:00   pic/ppt/media/image5.png
   186174  1980-01-01 00:00   pic/ppt/media/image4.png
   111613  1980-01-01 00:00   pic/ppt/media/image10.jpg
   426687  1980-01-01 00:00   pic/ppt/media/image1.png
---------                     -------
  1621686                     15 files

 

ただ、基本的にメディアファイルはすべて「ppt/media/」配下にあるのでそこだけ指定してやってもよかったかも。
「docProps/thumbnail.jpeg」ってサムネイルだしいらないと思われる。

 

Q4.

「20141019OSC_LT.pptx」のスライド7ページ目のテキストをスクレイピングする、という問題。
これについては、時間内に解くことができなかった。

で、@ebanさんの回答がやっぱりすごかったので、それ+@grethlenQ4の回答を参考にしたのが以下。
(ほとんど丸パクリのような気もしなくも…?)

unzip -p 20141019OSC_LT.pptx *slide7.xml | grep -oP '(?<=<a:p>).*?(?=</a:p>)' | sed 's/<[^>]*>//g' | awk NF
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ # スライド7枚目の情報だけ出力する
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -p 20141019OSC_LT.pptx *slide7.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/><a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr><p:sp><p:nvSpPr><p:cNvPr id="2" name="タイトル 1"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>戦果(? )</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="3" name="コンテンツ プレースホルダー 2"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph idx="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="457200" y="1599083"/><a:ext cx="8229600" cy="4708525"/></a:xfrm></p:spPr><p:txBody><a:bodyPr><a:normAutofit fontScale="92500" lnSpcReduction="10000"/></a:bodyPr><a:lstStyle/><a:p><a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>初日だけで見知らぬ方の</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>マシン</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0"/><a:t>3</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0"/><a:t>台轟沈</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/></a:p><a:p><a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0"/></a:p><a:p><a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>その他自爆者多数</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/></a:p><a:p><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/></a:p><a:p><a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" err="1" smtClean="0"/><a:t>Docker</a:t></a:r><a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>上で試したらホストマシン沈黙の報告</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/></a:p><a:p><a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0"/></a:p><a:p><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>自分の本がサイト経由で</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/><a:t>1</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>冊だけ売れた</a:t></a:r><a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/></a:p><a:p><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0"/></a:p><a:p><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>フォロワーが</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/><a:t>1</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>人減った</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="4" name="日付プレースホルダー 3"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="dt" sz="half" idx="10"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" smtClean="0"/><a:t>2014/10/19</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="5" name="フッター プレースホルダー 4"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ftr" sz="quarter" idx="11"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" smtClean="0"/><a:t>OSC Tokyo/Fall 2014</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="6" name="スライド番号プレースホルダー 5"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="sldNum" sz="quarter" idx="12"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:fld id="{14601655-C245-0940-ADDB-4E06ABBCA83C}" type="slidenum"><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" smtClean="0"/><a:t>7</a:t></a:fld><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/></a:p></p:txBody></p:sp></p:spTree><p:extLst><p:ext uri="{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}"><p14:creationId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="3384791587"/></p:ext></p:extLst></p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr><p:timing><p:tnLst><p:par><p:cTn id="1" dur="indefinite" restart="never" nodeType="tmRoot" xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"/></p:par></p:tnLst></p:timing></p:sld>
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ # grepでPerlの肯定先読み正規表現を用いて、「<a:p>~</a:p>(1行)」ごとに抽出する
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -p 20141019OSC_LT.pptx *slide7.xml | grep -oP '(?<=<a:p>).*?(?=</a:p>)'
<a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>戦果(?)</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0"/>
<a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>初日だけで見知らぬ方の</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>マシン</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0"/><a:t>3</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0"/><a:t>台轟沈</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/>
<a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0"/>
<a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>その他自爆者多数</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/>
<a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/>
<a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" err="1" smtClean="0"/><a:t>Docker</a:t></a:r><a:r><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>上で試したらホストマシン沈黙の報告</a:t></a:r><a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/>
<a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0"/>
<a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>自分の本がサイト経由で</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/><a:t>1</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>冊だけ売れた</a:t></a:r><a:endParaRPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/>
<a:endParaRPr kumimoji="1" lang="en-US" altLang="ja-JP" dirty="0"/>
<a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>フォロワーが</a:t></a:r><a:r><a:rPr lang="en-US" altLang="ja-JP" dirty="0" smtClean="0"/><a:t>1</a:t></a:r><a:r><a:rPr lang="ja-JP" altLang="en-US" dirty="0" smtClean="0"/><a:t>人減った</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US" dirty="0"/>
<a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" smtClean="0"/><a:t>2014/10/19</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/>
<a:r><a:rPr kumimoji="1" lang="en-US" altLang="ja-JP" smtClean="0"/><a:t>OSC Tokyo/Fall 2014</a:t></a:r><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/>
<a:fld id="{14601655-C245-0940-ADDB-4E06ABBCA83C}" type="slidenum"><a:rPr kumimoji="1" lang="ja-JP" altLang="en-US" smtClean="0"/><a:t>7</a:t></a:fld><a:endParaRPr kumimoji="1" lang="ja-JP" altLang="en-US"/>
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ # sedでタグ関係をすべて削除する
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -p 20141019OSC_LT.pptx *slide7.xml | grep -oP '(?<=<a:p>).*?(?=</a:p>)' | sed 's/<[^>]*>//g'
戦果(?)
初日だけで見知らぬ方のマシン3台轟沈

その他自爆者多数

Docker上で試したらホストマシン沈黙の報告

自分の本がサイト経由で1冊だけ売れた

フォロワーが1人減った
2014/10/19
OSC Tokyo/Fall 2014
7
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ # 空白行を削除する
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ unzip -p 20141019OSC_LT.pptx *slide7.xml | grep -oP '(?<=<a:p>).*?(?=</a:p>)' | sed 's/<[^>]*>//g' | awk NF
戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
2014/10/19
OSC Tokyo/Fall 2014
7

 

Q5.

「graph.xlsx」の内容を、SSV(スペース区切り)の形式で取得するという内容。
とりあえず、最も楽なxlsx2csvで回答した。

 

xlsx2csv -d' ' graph.xlsx
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ xlsx2csv -d' ' graph.xlsx
0 -5
0.5 -7.375
1 -14
1.5 -24.125
2 -37
2.5 -51.875
3 -68
3.5 -84.625
4 -101
4.5 -116.375
5 -130
5.5 -141.125
6 -149
6.5 -152.875
7 -152
7.5 -145.625
8 -133
8.5 -113.375
9 -86
9.5 -50.125
10 -5
10.5 50.125
11 116

 

xlsx2csvを使わない場合は、@grethlenこちらの回答が参考になる。

 

Q6.

「hanshin.xlsx」について、Q5と同様にSSV形式にするという問題。
こちらも、地味にxlsx2csvを使えばいい感じにやってくれはする。

xlsx2csv -d' ' hanshin.xlsx
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ xlsx2csv -d' ' hanshin.xlsx
 42522 42561
1 真弓 真弓
2 弘田 北村
3 バース バース
4 掛布 掛布
5 岡田 佐野
6 佐野 木戸
7 平田 平田
8 木戸 永尾
9 ゲイル 池田

 

とはいえ、それだと芸が無いので日付をUNIXTIMEに変換して加工、「YYYY年MM月DD日」形式で表示させてみる。
(ちょっと長い)

xlsx2csv -d' ' hanshin.xlsx | awk 'NR==1{for(i=1;i<NF;i++){cmd="date -d @$(echo $((("$i" - 25569) * 86400))) +%Y年%m月%d日";cmd|getline t;s=s" "t;close(cmd);}print s}NR!=1{print}'
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.26_work$ xlsx2csv -d' ' hanshin.xlsx | awk 'NR==1{for(i=1;i<NF;i++){cmd="date -d @$(echo $((("$i" - 25569) * 86400))) +%Y年%m月%d日";cmd|getline t;s=s" "t;close(cmd);}print s}NR!=1{print}'
 2016年06月01日 2016年07月10日
1 真弓 真弓
2 弘田 北村
3 バース バース
4 掛布 掛布
5 岡田 佐野
6 佐野 木戸
7 平田 平田
8 木戸 永尾
9 ゲイル 池田

 

で、xlsx2csvを使わないで回答する方法について。
Excelでは、Stringファイルについては「xl/sharedStrings.xml」に格納されているので、ここの内容をSheetのデータである「xl/worksheets/sheet1.xml」と組み合わせてやればよい。

Excelの「xl/worksheets/sheet1.xml」から「xl/sharedStrings.xml」の値の参照はデータの順番(というか、0から始まるので配列のようなイメージ。なんだそりゃ…)になっている。
xlsx2csvを使わない方法で解くとなると、模範解答のように2ファイルに分けて対応するのが一般的だと思う。

 

Q7&Q8

Q7とQ8はほぼほぼセットになっている。
Wordの特定の文字列を置換して、list.txtにある3名分の表彰状を作成するというもの。
(Wordの場合、確か差し込み印刷ってなかったっけ…?とも思ったが、印刷じゃないので気にしない)

とりあえず、以下の内容で回答した。

cat list.txt | xargs -n 1 -I@ sh -c 'unzip -d @ certificate.docx;sed -i s/WINNER/@/g @/word/document.xml;(cd @;zip -r ../@.docx ./)'

 

これで、「シェル芸おじさん.docx」などのファイルができているはずだ。
作業用のディレクトリ削除については行ってないので、ホントだったら消しといたほうがいいかも?

Perlの肯定正規表現については知らなかったので、あとで調べておきたい。

 

Pocket

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

*