【問題と解答】第27回sedこわいシェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら。

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.27

にあります。

クローンは以下のようにお願いします。

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

イントロ

環境

対象とするsedはGNU sedだけに絞っています。解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

Q1

次のechoの出力について、偶数番目の文字だけ大文字にしてください。できたら、奇数番目の文字だけ大文字にしてください。

$ echo abcdefghijklmn

解答

###偶数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\(.\)\(.\)/\1\U\2/g'
aBcDeFgHiJkLmN
###奇数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\(.\)\(.\)/\U\1\L\2/g'
AbCdEfGhIjKlMn
###-rを使うと多少スッキリする###
$ echo abcdefghijklmn | sed -r 's/(.)(.)/\U\1\L\2/g'
AbCdEfGhIjKlMn

Q2

seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。

解答

$ seq 1 100 | sed '0~3s/.*/Fizz/;0~5s/$/Buzz/' |
 sed 's/[0-9]*B/B/' | xargs

Q3

次の出力について、3行目を7行目の下に移動してください。

$ seq 1 10

解答

hで3行目をホールドスペースに突っ込み、Gでパターンスペースに戻します。

$ seq 1 10 | sed '3h;3d;7G'

Q4

次のコードのmainとahoの位置を入れ替えてください。

$ cat aho.cc 
#include <iostream>
using namespace std;

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}

void aho(void)
{
	cout << "aho" << endl;
}

解答

mainの部分をホールドスペースに入れる→消す→ファイルの一番後ろでホールドスペースを吐き出すという流れになります。

$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G'
#include <iostream>
using namespace std;


void aho(void)
{
	cout << "aho" << endl;
}

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}
###{}でまとめる###
$ cat aho.cc | sed '/int/,/}/{H;d};$G'
###もうちょっと厳密なやつ###
$ cat aho.cc | sed '/ main(/,/^}/{H;d};$G'
###そのままコンパイルして実行###
$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G' |
 g++ -x c++ - && ./a.out
aho

Q5

seq 1 10 | から始めて次のような出力を作ってください。

2
1
4
3
6
5
8
7
10
9

解答

$ seq 1 10 | sed '1~2h;1~2d;0~2G'
2
1
4
3
6
5
8
7
10
9

Q6

echo 1から始めて次のような出力を作ってください。

1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111

解答

ラベルを使います。

$ echo 1 | sed ':LOOP p;s/./&&/;b LOOP' | head
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111
###分岐を使う###
$ echo 1 | sed ':LOOP p;s/./&&/;/1\{10\}/!b LOOP'

Q7

aというファイルをtouch等で作り、次の縛りでa1, a2, a3, …, a10というファイルをaからコピーして作ってください。縛り1と縛り2を独立した別々の問題として解き、その後縛り1,2を両方満たす解を考えてみましょう。

  • 縛り1: 使うコマンドはseq、cp、sedだけ
  • 縛り2: ワンライナー中で数字を使わない

解答

###縛り1###
$ touch a
$ seq 1 10 | sed 's/./cp a a&/e'
$ ls a a? a10
a  a1  a10  a2  a3  a4  a5  a6  a7  a8  a9
###縛り2###
$ yes | sed -n '=' | head | sed 's/./cp a a&/e'
###両方###
$ sed ':a ;p;s/./&&/;/........../!b a' <<< y |
 sed -n = | sed 's/^/cp a a/e'
###(おまけ)ファイルaをsedで作る###
$ sed 'w a' <<< "abc"
abc
$ cat a
abc

Q8

echo 1 | から始めて、あとはsedだけで次のような出力を得てください。

1
11
111
1111
11111
11111
1111
111
11
1

解答

$ echo 1 | sed ':LOOP p;s/./&&/;/1\{5\}/!b LOOP' | sed 'p;1!G;h;$!d'
1
11
111
1111
11111
11111
1111
111
11
1
Pocket
LINEで送る

【問題のみ】第27回sedこわいシェル芸勉強会

Pocket
LINEで送る

解答例はこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.27

にあります。

クローンは以下のようにお願いします。

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

イントロ

環境

対象とするsedはGNU sedだけに絞っています。解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。GSD系の人は玄人なので各自対応のこと。

Q1

次のechoの出力について、偶数番目の文字だけ大文字にしてください。できたら、奇数番目の文字だけ大文字にしてください。

$ echo abcdefghijklmn

Q2

seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。

Q3

次の出力について、3行目を7行目の下に移動してください。

$ seq 1 10

Q4

次のコードのmainとahoの位置を入れ替えてください。

$ cat aho.cc 
#include <iostream>
using namespace std;

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}

void aho(void)
{
	cout << "aho" << endl;
}

Q5

seq 1 10 | から始めて次のような出力を作ってください。

2
1
4
3
6
5
8
7
10
9

Q6

echo 1から始めて次のような出力を作ってください。

1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111

Q7

aというファイルをtouch等で作り、次の縛りでa1, a2, a3, …, a10というファイルをaからコピーして作ってください。縛り1と縛り2を独立した別々の問題として解き、その後縛り1,2を両方満たす解を考えてみましょう。

  • 縛り1: 使うコマンドはseq、cp、sedだけ
  • 縛り2: ワンライナー中で数字を使わない

Q8

echo 1 | から始めて、あとはsedだけで次のような出力を得てください。

1
11
111
1111
11111
11111
1111
111
11
1
Pocket
LINEで送る

第26回シェル芸勉強会及びエクシェル芸勉強会リンク集

Pocket
LINEで送る

今更ですが・・・

次回は2月11日 or 18日で調整中です。

当日の様子

午前

午後

イントロ

第26回シェル芸勉強会及びエクシェル芸勉強会
 

問題

こちら

まとめ

サテライト会場の様子

福岡

大阪

LT(とりあえず東京のアップされてる分)

スライドアップしたら教えてくださーい!

Pocket
LINEで送る

【問題と解答】第26回シェル芸勉強会及びエクシェル芸勉強会

Pocket
LINEで送る

問題のみのページはコチラ

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.26

にあります。

クローンは以下のようにお願いします。

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

環境

シェル芸を行うのはUbuntu Linux 16.04です。確認はMacのExcelやWord, PowerPointで行いました。今回は特にワンライナーにこだわる必要はありません。シェルスクリプトにしても構いません。もちろん、一般解にこだわる必要もありません。

イントロ

第26回シェル芸勉強会及びエクシェル芸勉強会

Q1

.xlsxや.docx、.pptxファイルはzipファイルです。リポジトリの中のxlsx,docx,pptxを展開し、中にどんなファイルがあるか見て、再び戻して再び.xlsx,.docx,.pptxファイルとして開いてみてください。

解答

解凍すると、一つのディレクトリに収まってなく、その場にいくつかのファイルが展開されるので厄介です。ファイルの置き場所と展開する場所を分けましょう。

$ mkdir ~/tmp
$ cd ~/tmp
###tmpの下に置かずに解凍###
$ unzip ~/ShellGeiData/vol.26/graph.xlsx 
ueda@remote:~/tmp$ ls
[Content_Types].xml  _rels  docProps  xl
ueda@remote:~/tmp$ tree
.
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   ├── core.xml
│   └── thumbnail.jpeg
└── xl
    ├── _rels
    │   └── workbook.xml.rels
    ├── calcChain.xml
    ├── charts
    │   └── chart1.xml
    ├── drawings
    │   ├── _rels
    │   │   └── drawing1.xml.rels
    │   └── drawing1.xml
    ├── styles.xml
    ├── theme
    │   └── theme1.xml
    ├── workbook.xml
    └── worksheets
        ├── _rels
        │   └── sheet1.xml.rels
        └── sheet1.xml

10 directories, 14 files
###再圧縮したファイルも別のディレクトリに作ると事故が少ない###
ueda@remote:~/tmp$ zip -r ../hoge.xlsx ./

Q2

20141019OSC_LT.pptxのスライドに何回「危険」という単語が出てくるか数えてください。画像になっているものは除きます。

解答

$ unzip ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ;
grep -o 危険 ppt/slides/slide* | wc -l
17

unzipは-pオプションで必要なファイルだけcatすることができます。ということで次のようにすると完全にワンライナーになります。

$ unzip -p ~/ShellGeiData/vol.26/20141019OSC_LT.pptx 'ppt/slides/slide*' |
 grep -o 危険 | wc -l
17

Q3

20141019OSC_LT.pptxのスライドから画像を抽出して、一つのディレクトリにまとめてzipで固めてください。

解答

$ unzip ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ;
 zip -r media.zip ./ppt/media/

Q4

20141019OSC_LT.pptxのスライドの7ページ目のテキストをスクレイピングしましょう。以下が出力の例です。

戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
(以下、フッタ等の文字列が混ざっても可とします)

解答

$ unzip -p ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ppt/slides/slide7.xml |
 xmllint --format - | grep '<a:[pt]>' | sed 's;</.*;;' |
 sed 's;<.*>;;' | awk 'NF==0{print "@@@"}{print}' |
 xargs | sed 's/@@*/\n/g' | awk 'NF' | tr -d ' '
戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
2014/10/19
OSCTokyo/Fall2014
7

Q5

graph.xlsxの2列の数字を抜き出して端末にSSV形式のデータ(CSVのカンマがスペースになったもの)、あるいはセルの番号と値のリストとして抜き出してください。

解答

###スペース区切り###
$ unzip ~/ShellGeiData/vol.26/graph.xlsx;
 cat xl/worksheets/sheet1.xml |
 sed 's;</row>;\n;g' | sed 's;</v>.*<v>; ;' |
 sed 's;.*<v>;;' | sed 's;</v>.*;;' | grep -v "^<"
###スペース区切り・ワンライナーバージョン###
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 sed 's;</row>;\n;g' | sed 's;</v>.*<v>; ;' |
 sed 's;.*<v>;;' | sed 's;</v>.*;;' | grep -v "^<"

もっとスマートに行うには、html-xml-utilsとlibxml2-utilsをインストールしてhxselectコマンドやxmllintを使います。

$ sudo apt install html-xml-utils
$ sudo apt install libxml2-utils
###番号と値のリスト###
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 hxselect c -s '\n' | sed 's;[^=]*=";;' |
 sed 's;".*<v>; ;' | sed 's;<.*;;'
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 xmllint --format - | grep -e '<c r=' -e '<v>' | xargs |
 sed 's;</v>;\n;g' | sed 's/.*=//' | sed 's/>.*>/ /'

もっと便利なツールもあるという噂ですが、とりあえず私からこれくらいで・・・

Q6

hanshin.xlsxのシートについてQ2と同様SSV形式か、セルの番号と値のリストとして端末上に出力してください。日付のセルについては何を出力しても良いことにします。

解答

文字列は展開したファイルのxl/sharedStrings.xmlに順番に入っています。

$ unzip ~/GIT/ShellGeiData/vol.26/hanshin.xlsx 
$ xmllint --format xl/sharedStrings.xml  | head
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="18" uniqueCount="15">
  <si>
    <t>真弓</t>
    <rPh sb="0" eb="2">
      <t>マユミ</t>
    </rPh>
    <phoneticPr fontId="1"/>
  </si>
  <si>

読みのデータが邪魔なので、消去した上でリストを作っておきます。

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/sharedStrings.xml |
 hxselect si -s '\n' | awk -F'[<>]' '{print NR-1,$5}' > strings
$ head -n 3 strings 
0 真弓
1 弘田
2 バース

次に、シートのデータを加工していきます。文字列のセルには「t=”s”」という属性があるので、これで文字列のセルと数字のセルを分けます。文字列のセルのv要素にある数字は、sharedStrings.xmlの何番目の文字列がこのセルに入るかを意味します。(sharedStrings.xmlはXMLファイルなのにデータの並び順で文字列を管理しているという・・・)

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/worksheets/sheet1.xml |
  hxselect c -s '\n' | grep '<v>' |
 awk -F'[<> "]' '/t="s"/{print $4,"s",$(NF-4)}!/t="s"/{print $4,"n",$(NF-4)}'
B1 n 42522
C1 n 42561
A2 n 1
B2 s 0
C2 s 0
A3 n 2
B3 s 1
C3 s 9
A4 n 3
B4 s 2
...

ここまでできたら、awkで無理やり文字列のファイルとデータのファイルを混ぜて答えを出します。この例ではFILENAMEという変数を使っています。

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/worksheets/sheet1.xml |
 hxselect c -s '\n' | grep '<v>' |
 awk -F'[<> "]' '/t="s"/{print $4,"s",$(NF-4)}!/t="s"/{print $4,"n",$(NF-4)}' |
 awk 'FILENAME=="strings"{s[$1]=$2}FILENAME=="-"&&
$2=="s"{print $1,s[$3]}$2=="n"{print $1,$3}' strings -
B1 42522
C1 42561
A2 1
B2 真弓
C2 真弓
A3 2
B3 弘田
C3 北村
A4 3
B4 バース
C4 バース
A5 4
B5 掛布
C5 掛布
A6 5
B6 岡田
C6 佐野
A7 6
B7 佐野
C7 木戸
A8 7
B8 平田
C8 平田
A9 8
B9 木戸
C9 永尾
A10 9
B10 ゲイル
C10 池田

Q7

certificate.docxファイルを開いて確認し、人の名前が入るところに好きな名前を入れてみましょう。

解答

ホームの下にtmp等の一時ディレクトリを作ってそこで試しましょう。-iオプションは、BSD系のsedの場合-i.bakと言うように拡張子をつけてバックアップファイルを作らなければなりませんが、その場合はバックアップファイルを消してから再圧縮します。

###~/tmp/で作業すると仮定します###
$ unzip ~/ShellGeiData/vol.26/certificate.docx ; 
sed -i 's/WINNER/しぇる芸のオッサン/' word/document.xml ; 
zip -r ../hoge.docx ./
###ワーニングが出ますが開けます###

Q8

Q7を応用し、次のリストlist.txtで、複数の表彰状を作ってみましょう。

$ cat list.txt 
シェル芸おじさん
シェル芸野郎
変態シェル芸豚野郎

解答

unzipに-o(overwrite)オプションをつけると便利です。

$ cat ~/ShellGeiData/vol.26/list.txt | 
while read name ; do unzip -o ~/ShellGeiData/vol.26/certificate.docx ;
 sed -i "s/WINNER/$name/" word/document.xml ;
 zip -r ../$name.docx ./ ; done
Pocket
LINEで送る

【問題のみ】第26回シェル芸勉強会及びエクシェル芸勉強会

Pocket
LINEで送る

解答はコチラ

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.26

にあります。

クローンは以下のようにお願いします。

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

環境

シェル芸を行うのはUbuntu Linux 16.04です。確認はMacのExcelやWord, PowerPointで行いました。今回は特にワンライナーにこだわる必要はありません。シェルスクリプトにしても構いません。もちろん、一般解にこだわる必要もありません。

イントロ

第26回シェル芸勉強会及びエクシェル芸勉強会

Q1

.xlsxや.docx、.pptxファイルはzipファイルです。リポジトリの中のxlsx,docx,pptxを展開し、中にどんなファイルがあるか見て、再び戻して再び.xlsxファイルとして開いてみてください。

Q2

20141019OSC_LT.pptxのスライドに何回「危険」という単語が出てくるか数えてください。画像になっているものは除きます。

Q3

20141019OSC_LT.pptxのスライドから画像を抽出して、一つのディレクトリにまとめてzipで固めてください。

Q4

20141019OSC_LT.pptxのスライドの7ページ目のテキストをスクレイピングしましょう。以下が出力の例です。

戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
(以下、フッタ等の文字列が混ざっても可とします)

Q5

graph.xlsxの2列の数字を抜き出して端末にSSV形式のデータ(CSVのカンマがスペースになったもの)、あるいはセルの番号と値のリストとして抜き出してください。

Q6

hanshin.xlsxのシートについてQ2と同様SSV形式か、セルの番号と値のリストとして端末上に出力してください。日付のセルについては何を出力しても良いことにします。

Q7

certificate.docxファイルを開いて確認し、人の名前が入るところに好きな名前を入れてみましょう。

Q8

Q7を応用し、次のリストlist.txtで、複数の表彰状を作ってみましょう。

$ cat list.txt 
シェル芸おじさん
シェル芸野郎
変態シェル芸豚野郎
Pocket
LINEで送る

第25回もう4年もやってんのかシェル芸勉強会リンク集

Pocket
LINEで送る

2016年10月29日(土曜日)、さくらインターネットさんで行いました。横田さんはじめサテライトの皆様、東京の参加者のみなさまありがとうございました。

大体のリンクはTogetterにありますので、ここではビデオへのリンクだけ・・・(だんだん簡略になってますが・・・)

Pocket
LINEで送る

【問題のみ】第25回もう4年もやってんのかシェル芸勉強会

Pocket
LINEで送る

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.25

にあります。ただ、今回は1つしかファイルがありません。

クローンは以下のようにお願いします。

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

環境

今回はUbuntu Linux 16.04で解答例を作りました。

Q1

www.usptomo.comのIPアドレスだけを出力するワンライナーを考えてみてください。

Q2

次のような出力を作ってください。(出典

ひらけ!ポンキッキ
らけ!ポンキッキひ
け!ポンキッキひら
!ポンキッキひらけ
ポンキッキひらけ!
ンキッキひらけ!ポ
キッキひらけ!ポン
ッキひらけ!ポンキ
キひらけ!ポンキッ

Q3

rbashと打つとリダイレクトが使えなくなります。

この状況で、/etc/passwdからbashをログインシェルにしているユーザのレコードを抽出し、hoge等のファイルに出力してみましょう。様々な方法を考えてみましょう。bashと打ったりexitでもとのbashに戻るのは反則とします。

Q4

以下のひらがなからワンライナーを始めて、濁点がつく字だけに濁点をつけてみてください。

$ echo すけふぇにんけん

Q5

1秒に一つ*が伸びていくアニメーションを作ってください。

Q6

日本語のメッセージから作った次の文字列を復元してください。

$ cat crypt 
b730a730eb30b8820a00

Q7

本日(2016年10月29日)の範囲の毎秒のUNIX時刻で素数となるものを全て列挙してください。出力はUNIX時刻でなく、何時何分何秒か分かるようにしましょう。世界標準時で考えてください。

Q8

次のようにサイン波を描いてください。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-27-21-04-17

Pocket
LINEで送る

第24回◯◯o◯裏番組シェル芸勉強会リンク集

Pocket
LINEで送る

今回も無事に濃く終了いたしました。KDDIウェブコミュニケーションズ様はお引っ越しということで、麹町での開催は今回が最後となりました。ありがとうございました。

それから、今回東京がまったりだったので大阪のLTを無理言って見せてもらいました。濃さをリアルタイムで確認できて東京では悲鳴が上がっておりました。ありがとうございました。

以下、今回の発表等のリンクです。

あ、いつも1/3くらいの人は初参加ですので、次回もお気軽に。

まとめ

ビデオ

午前

午後

サテライト会場

いつもありがとうございます。

午前のスライド

私のはman gawk(日本語版)を見ながらやったのでナシです。

ブログ

宣伝

シェル芸普及のために売らねばならんという使命感により。

Pocket
LINEで送る

【問題と解答】第24回◯◯o◯裏番組シェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら

イントロ

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.24

にあります。

クローンは以下のようにお願いします。

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

環境

今回はUbuntu Linux 16.04で解答例を作りました。

Q1

$ cat Q1
玉子 卵 玉子 玉子 玉子 玉子
玉子 玉子 卵 卵 卵 玉子
卵 玉子 卵 玉子 玉子 玉子
卵 玉子 卵 卵 卵 卵
玉子 卵 玉子

上のようなQ1ファイルについて、次のような出力を得てください。

玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

解答

AWKの力技になります。力技でない方法を募集。

$ cat Q1 |
 awk '{for(i=1;i<=NF;i++){a[$i]++};for(k in a){printf("%s:%d ",k,a[k]);a[k]=0}print ""}'
玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

Q2

次のようなテキストについて、繰り返し出てきた文字の2つ目以降を省いて出力してください。例えばQ2のファイル

$ cat Q2
へのへのもへじ

の場合、「へのもじ」が正解の出力になります。

解答

$ cat Q2 | grep -o . | nl | sort -k2,2 -k1,1n |
 uniq -f 1 | sort | awk '{printf $2}' | xargs
へのもじ
$ cat Q2 | grep -o . | awk '{if(!a[$1]){printf $1};a[$1]=1}END{print ""}'
へのもじ
$ < Q2 grep -o . | awk '{if(!a[$1]){printf $1};a[$1]=1}' | xargs
へのもじ

Q3

$ cat Q3
金 日成
キム ワイプ
金 正日
キム タオル
金 正男

というデータを、

%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

というように第一フィールドをキーにして%%でレコードを区切ってください。awkを使ってできた人は、awkを使わないでやってみてください。

解答

$ sort Q3 | awk '{if($1!=a){print "%%";print;a=$1}else{print}}END{print "%%"}'
%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%
$ sort Q2 | rev | uniq --group=both -f 1 | rev | sed 's/^$/%%/'
%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

Q4

Q4.xlsxのA1のセルには数字が書いてあります。その数字を出力してください。A4には文字列が書いてあるので余裕がある人はそれも特定してみましょう。

解答

A1のセル(数字の読み方)

$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml | sed 's;</c>;&\n;g' |
 grep -o '<c.*</c>' | grep A1 | sed 's;.*<v>;;' | sed 's;<.*;;'
114514
$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml | hxselect -s '\n' c |
 grep A1 | hxselect -c v
114514

A2の文字列の読み方。シートには文字列のIDが書いてあるのでこれで文字列のシートを読んで特定。

###これで6番目(0番から始まるので7番目)の文字列とわかる###
$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml |
 hxselect -s '\n' c | grep A4
<c r="A4" t="s"><v>6</v></c>
###抽出###
$ unzip -p Q4.xlsx xl/sharedStrings.xml |
 hxselect -s '\n' si | awk 'NR==7'
<si><t>エクシェル芸</t><rPh sb="5" eb="6"><t>ゲ</t></rPh><phoneticPr fontId="1"/></si>

Q5

ファイルQ5について、xに好きな数を代入して各行の式を計算してください。

$ cat Q5
x + x^2
x + 1/x
x*x*x

余裕のある人は、例えばxに2を代入したければ、

$ echo 2 | ...

というようにecho <代入したい数>から始めてワンライナーで解いてみてください。

解答

例えばこれで解けます。(-2)のカッコはQ5ファイルでは不要なようです。

$ sed 's/x/(-2)/g' Q5 | bc -l
2
-2.50000000000000000000
-8

echo <数字>からスタートすると、ややこしくなります。

$ echo -2 | xargs -I@ awk -v a=@ '{gsub(/x/,a,$0);print}' Q5 | bc -l
2
-2.50000000000000000000
-8

Q6

「玉子」と「卵」の数を数えて、数が少ない方を数が大きい方で置換してください。

$ cat Q6 
卵卵玉子玉子玉子玉子玉子卵卵卵玉子玉子卵玉子玉子玉子玉子卵卵玉子卵玉子卵卵玉子卵玉子

解答

力技です。

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c |
 sort -n -k1,1n | awk '{print $2}' | xargs |
 awk '{print "s/"$1"/"$2"/g"}' | xargs -I@ sed @ Q6
玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子

Q7

次のseq(あるいはjot等)の出力から、各桁の数字の構成が同じもの(例: 11122と22111等)を重複とみなし、除去してください。

$ seq -w 00000 99999

解答

###asortを使う場合###
$ seq -w 00000 99999 | sed 's/./& /g' |
 awk '{for(i=1;i<=NF;i++)a[i]=$i;asort(a);for(k in a){printf a[k]}print ""}' |
 sort -u
###ちょっと気の利いた方法(数字が小さい順に並んでいるものだけ残す)###
$ seq -w 00000 99999 | sed 's/./& /g' |
 awk '$1<=$2&&$2<=$3&&$3<=$4&&$4<=$5' | tr -d ' ' 

Q8

1. まず、1〜7を全て含む7桁の整数を全て列挙して、tmpというファイルに出力してください。

2. 次に、相異なる7以下の正の整数a,b,c,d,e,f,gを用いて、

abcd + efg

と表せる素数と、その時のa〜gの数字を全て求めましょう。tmpを用いて構いません。

(参考: 2011年日本数学オリンピック予選第3問から。一部改。http://www.imojp.org/challenge/old/jmo21yq.html

解答

1は力技になります。

$ seq -w 0000000 9999999 | grep -v [089] |
 grep 1 | grep 2 | grep 3 | grep 4 | grep 5 | grep 6 | grep 7 > tmp

2は、うまくwhileとfactorを使って求めます。

$ cat tmp | sed 's/./& /g' | awk '{print $1$2$3$4$5$6$7,$1*$2*$3*$4+$5*$6*$7}' | while read a b ; do echo $b | factor | awk -v n=$a 'NF==2{gsub(/./,"& ",n);print n,$2}' ; done 
2 3 4 6 1 5 7  179
2 3 4 6 1 7 5  179
2 3 4 6 5 1 7  179
2 3 4 6 5 7 1  179
2 3 4 6 7 1 5  179
2 3 4 6 7 5 1  179
2 3 6 4 1 5 7  179
2 3 6 4 1 7 5  179
2 3 6 4 5 1 7  179
...
Pocket
LINEで送る

第24回シェル芸勉強会のサテライト会場(大阪・福岡)

Pocket
LINEで送る

東京がもう定員オーバーですが、今回も福岡と大阪でサテライト会場をご用意いただきました。いつもありがとうございます。

ぜひぜひ。

東京あるいは津田沼でもサテライト会場が・・・いいえなんでもありません。

Pocket
LINEで送る