第30回シェル芸勉強会:福岡サテライト レポート

シェル芸 ver.30 勉強会Report

第30回危念シェル芸 5周年おめでとうございます。久しぶり参加しました。 総じて楽しかったです。内容は午前の部と午後の部と2部構成でした。

atnd.org

午前の部

  • やりたい文字列と正規表現があって、その間を記号で繋げる
  • 正規表現自身に、SLASHが入るときは、Bracketを使うと見やすい
  • 変数展開でさまざまな文字列を指定文字列に変換できる* RubyPerlのを参考にして作られた言語
  • iをつけると、大文字小文字を区別しない
  • s/ / /s シングルラインモード
  • コンテキストの概念が重要(スカラーコンテキスト or リストコンテキスト)
  • ^もキャレットアンカー、$もドルアンカーっていう言い方をするらしい
  • クラシックなPerl文字class
  • クラシック文字クラスは大文字にすると否定
  • echo 1 2 3 4 5 | perl -pe ’s/\d+/sin($&)/eg' eg でperlとして実行できる
  • Unicode属性 InとIsがある
  • アンカー 単語境界
  • クロイスタ パターンを無効化
  • ルックアラウンドアサーション 先読みと後読みで達人の領域らしい

Perl正規表現第2回めでしたが、スライド進む度だんだん難易度が上がってる気がしてて 難しく感じたのもありましたが、スライドとターミナルと交互に実行結果などで 説明頂きました。Youtureに残していただいてるのであとから見直すことも出来ありがたかったです。

午後の部

  • 案件ネタ(html、ネットワーク)
  • パズル(脳みそに電極)

Q1

$ tree posts
posts
├── 20170806_check_of_webhook
│   └── main.md
├── 20170810_negi
│   ├── green_negi.jpg
│   ├── main.md
│   ├── white_negi.jpg
│   └── ねぎ.pdf
├── 20170810_negistagram
│   └── main.md
├── 20170812_work
├── 20170812_working
│   └── main.md
├── 20170814_layout
│   └── main.md
├── 20170818_bash
│   └── main.md
├── 20170820_bootstrap
│   └── main.md
├── 20170820_injection
│   └── main.md
└── template
    └── main.md
  • この中の、各main.mdは次のようなヘッダ付きのマークダウンです。
$ cat posts/20170818_bash/main.md 
---
Keywords: 嫌がらせ
Copyright: (C) 2017 Ryuichi Ueda
---
 
# 検索機能への嫌がらせ
Keywords: ワッショイ
Keywords: ワッショイ
Keywords: ワッショイ
  • これらのファイルから、次のような出力を作ってください。なお、Keywordsの行は各ファイルで最初にある行しか抽出しないこととします。
20170806_check_of_webhook Keywords: Webhook
20170810_negi Keywords: ネギ
20170810_negistagram Keywords: Twitter, Instagram, ネギ
20170812_working Keywords: 働けども働けども, bashcms2
20170814_layout Keywords: table, 雑
20170818_bash Keywords: 嫌がらせ
20170820_bootstrap Keywords: Bootstrap
20170820_injection Keywords: injection
template Keywords: 

$ ggrep -nr ‘Keyword’ ./ | ggrep ‘/main.md:2:’ | gsed ’s;./posts/;;‘ | gsed ’s;/main.md:2:; ;’

2行目がコメントだったので、grep -n オプションを使用 grep -m 1 で1行表示することもできるということを知った。grep 奥が深いなと感じました。

Q2

  • 次のHTMLファイルurl.htmlについて、リンクが相対パスになっているものについては頭に/files/をつけて、/から始まっているものとhttpやhttpsから始まっているものはそのままにしてください。できる人は変なところに改行があるものなどに対応できるように、なるべく一般解に近づけましょう。
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <ul>
    <li><a href="./hoge.html">ほげ</a></li>
    <li><img src="ayasii.jpg" alt="怪しい" /></li>
    <li><a href="https://blog.ueda.tech/">クソブログ</a><a href="huge.html">ふげ</a></li>
    <li><a href="/root.jpg"></a>これはそのまま</li>
    <li><a href="http://www.usptomo.com/">更新してない</a></li>
  </ul>
</body>
</html>

$ cat url.html | sed -r ’s;(img src=“|a href=”);&/files/;g' | sed -r ’s;(href=“|src=”)/files//;\1/;‘ | sed -r ’s;(href=“|src=”)/files/(https://|http://);\1\2;g’ | sed ’s;/./;/;g'

sed で頑張って変える感じでした。sed -r のバックスラッシュが省略がしらなかった sedの使い方がスマートでした。

Q3

次のファイルについて、

$ cat list
* 妬み
* 嫉み
* 僻み

次のようにHTMLにして、頭にHTTPヘッダをつけてください。インデントは不要ですがタグは1行1個でお願いします。

Content-Type: text/html
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
<ul>
<li>妬み</li>
<li>嫉み</li>
<li>僻み</li>
</ul>
</body>
</html>

すぐできて退屈な人は、インターネット上のサーバでこのHTMLファイルを送信するサーバをワンライナーで立ててください。

$ pandoc list -t html5 -s | sed ‘5,12d’ | sed ‘1iContent-Type: text/html\n’

知らなかった、「pandoc」コマンド。めちゃくちゃいい。 今までhtml5はテンプレートを予めsnippetとかで作ってたので、今後はそんな手間もなくなりそう。 その他にも色んな種類があるので、使い分けていきたい。

htmlファイルを送信するサーバをワンライナーで立てるということで、nc コマンドを教わった。 オプションが充実しててスゴイ役立ちそうな印象。

Q4

&&や;でコマンドを繋いだワンライナーで、GitHubリポジトリを作ってそこにテキストファイルを一つ置いてください。

mkdir hoge && cd hoge && git init && echo aho > aho.txt && git add -A && git commit -m “aho” && hub create ryuichiueda/hoge && git push origin master

&& でワンライナーで別々のコマンド叩けるんだなぁという印象。hubコマンド便利

Q5

次のファイルの1行目の複素数と2行目の複素数をかけ算してください。

$ cat complex 
1 + 4*i
3 - 2*i

$ cat complex | sed ’s/^/(/‘ | sed ’s/$/)/’ | sed ‘2,$i*’ | xargs | tr -d ‘ ’ | xargs -I@ perl -e ‘{use Math::Complex;print(@);print “\n”}’ 11+10i

TwitterのTLでは、いろんなのをくぐらせて答えを出していて、用途は様々だなと見てて楽しかったです。

cat complex | awk ‘BEGIN{FS=“ ”}/1/{a=$1;b=$2 $3};/2/{c=$1;d=$2 $3};END{r=ac-bd;i=ad+bc;print r (i<0?“-”:“+”) i “i” }’

Q6

フィボナッチ数列で、6765の4つ前の数を出力してください。

$ echo a | awk ‘BEGIN{a=1;b=1}{while(1){print a;c=b;b+=a;a=c}}’ | grep -m 1 -B4 6765 | head -n 1 987

Q7

次の数字の列について、00, 01, 02,…,99の数字2つ並びのうち、含まれないものを抽出してください。できる人はループを使わないで抽出してください。

$ seq -w 0 99 | while read n ; do grep -q $n nums || echo $n ; done

Q8

次のアルファベットの区間のうち、間に含まれるアルファベットが一番多いものはどれでしょうか。出力は何行目に書いてある区間かを数字で出せば良いこととします。

$ cat alphabet 
a-g
e-q
z-v
r-y

$ cat alphabet | awk ‘{a=$1;gsub(/-/,“..”,a);print “echo”,$1,“{"a”}“}’ | bash | awk ‘{print $1,NF}’ | sort -k2,2n | tail -n 1 | awk ‘{print $1}’

午後の部おわって

福岡では、コマンドを使ってて出た疑問について質問しました。

コマンドの文字列長に制限があるから、大量のファイルを処理するときにどう扱えばいいのか?

OSのヘッダーファイルにかかれていて、設定がある

問題点

  • 処理できる長さ制限

解決策

  • xargs を使うと、kernelができるところまでやって、オーバーしそうになったら次に行くように進める

xargs で問題なるところ

  • 時刻別で並び替えたいときの問題

xargs のオプションでなれておくこと

  • -I@ で指定の場所に標準入力の出力結果を@ でおくことができる

  • -P background処理

  • -n 1 ひとつずつ実行(コマンドによって、単一ファイル前提)

以下のテクニックは知っておいてすごく便利だなと使って思ったので、使いこなしたいなと思いました。また機会があれば参加したいです。 ありがとうございました。

pandoc
cat - <(seq 1 10)
nc