jus共催第27回シェル芸勉強会のリンク集

Pocket
LINEで送る

2017年2月11日(土曜日)にさくらインターネットさんにて開催しました。日本UNIXユーザ会(jus)さんとの共催でした。

sedに絞って機能を使ってみる出題にしたのでいつもより勉強会っぽい勉強会になりました。最後の三問が急に難しくなって「ハシゴを外された」との声もありましたが・・・。

酸化参加された皆様、会場を提供いただいたさくらインターネットさん横田さん、午前の部の講師の鳥海さん石井さん、ストリーミングを担当された宮川さん、濃いLT勢の皆様、jusのりゅうちさん、Twitter勢の皆様、そしてサテライト会場の皆様、ありがとうございました。

問題

 

録画

サテライト会場

まとめ

ブログ等

多すぎるので今回からまとめのところからのリンクで代用させていただきます・・・

番外編

翌日の別の勉強会で危険シェル芸が炸裂したそうです・・・

Vimシェル芸の予感・・・

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をつかいましょう。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で送る

やっと論文の「, . 」と、その他原稿の「、。 」を使い分ける(自分にとっての)究極の方法を見つけた

Pocket
LINEで送る

ここ数年の問題が解決しました。こうやれば良かったんです。何故気付かなかったのか。

研究者は普通、デフォルトで句読点を「, .」(カンマとピリオド)にしてますが、私のようなエセの場合、学術的な文章とそうでない文章が半々で使い分けないといけません。1日に何度も切り替えるのも馬鹿馬鹿しいので、普段は「、。」で書いて、論文もそのまま「、。」で書いて後でvimで変換してました。ただ、これだと論文を出すときに変換忘れをやらかしそうでなんか落ち着きません。

しかし考えてみたら、論文は必ずpLaTeXで書いてmakeしているので、上のツイートのようにMakefileに変換を仕込んでおけばよかったと。なぜ今の今まで考えつかなかったのかと。ということでMakefileを晒しておきます。コンパイル対象のファイル名を変えたらMacとかLinuxとかBSDとかで普通に使えると思います。

uedambp:RSJ2015 ueda$ cat Makefile 
rsj2015.pdf: rsj2015.dvi
	dvipdfmx -p a4 rsj2015.dvi

rsj2015.dvi: *.tex
	sed -i.bak -e 's/。/. /g' -e 's/、/, /g' rsj2015.tex
	platex rsj2015.tex
	pbibtex rsj2015.aux
	platex rsj2015.tex
	platex rsj2015.tex

clean:
	rm -f *.aux *.log *.dvi *.bbl *.blg *.pdf *.ilg *.idx *.toc *.ind

6行目のsedで、-i.bakで「ファイルの中身を出力で入れ替えて、拡張子.bakのバックアップファイルを作る」という意味になります。Vimから:!makeした場合だと、コンパイルが終わったらVimが「編集中にファイルが変わっちまった」とワーニングを出すので、再ロードして変更を読み込みます。

ところで、こういう話は「、。」と「, .」どっちが正しいという炎上案件になりがちですが、ここではそういう議論はしません。誰が何を言おうと論文のフォーマットとして句読点を「,.」で出せと言ってくるわけでして、それに従順に従っているにすぎません。

ところで、rst2015.texとう名前の通り、そういう学会に向けて何か書いておるわけですが、まだ書けてません。期限が延長されてよかったよかった・・・。

Pocket
LINEで送る

reStの一部の記号を消すシェルスクリプト作ったった

Pocket
LINEで送る

以前から燻りながら地味にページ数を稼いでいる「これ」と「これ」ですが、あまり引っ張るのもよろしくないので私なりに解決しました。

@tcsh氏からSphinx陣営に引き込まれそうになりましたが、私はそんなにでかいPythonのコードを書いた事も無ければ、研究しないと数年後に失職する身分なので逃げます

Python書かなくても、私については次のようなシェルスクリプトを原稿のディレクトリに置いておけば事足ります。reStの*前後の空白を*ごと潰し、2連バッククォートを取り去って標準出力に出します。適当ですが、何かあったらまた改造すりゃいいだけの話です。

uedamac:pub ueda$ cat remove_space 
#!/bin/bash

sed 's/ \*//g'	|
sed 's/\* //g'	|
sed 's/^\*//'	|
sed 's/\*$//'	|
sed 's/ *`` *//g'

つかってみましょう。

uedamac:pub ueda$ echo '``だっ`` *ふん* だ' | ./remove_space > ./for_pub.txt
uedamac:pub ueda$ cat for_pub.txt
だっふんだ

for_pub.txtとSphinxで作ったHTMLを編集様に送る事にします。数ヶ月後に、1ページにデカデカと「だっふんだ」と書かれた雑誌が出版されます。南無阿弥陀仏。

やっぱり、ライブラリの中にいろいろ書くよりも、こっちの方が私には性に合っています。Sphinxも、もっとコマンド仕立てにすればいいのに・・・(ボソ)。

だっふんだ。

Pocket
LINEで送る