LoginSignup
12
11

More than 5 years have passed since last update.

パイプ大好き

Posted at

日々良く使っていそうなパイプによる連結。「パイプはモナド!!」とか言いたい方は是非こちらへ。

行数を数えたい

単純に行数を数えたい場合は wc -l で十分です。wc は word count で、-l は line number を教えろという意味です。

$ netstat -tn | wc -l
34

でも何だか味気ないです。exact match でその行がどれくらいあるの? みたいなのが知りたい場合には sortuniq を併せて使います。

$ netstat -tn | awk '{print $6}' | sort | uniq | wc -l
5

uniq は連続した重複行を 1 行にまとめてくれるので、sort を前にかまします。uniq-c を付けるとその重複行が何行あったか教えてくれて便利です。

$ netstat -tn | awk '{print $6}' | sort | uniq -c
      1
      1 CLOSE_WAIT
     32 ESTABLISHED
      1 TIME_WAIT
      1 状態

sort-n で文字列ではなく数字として sort、-r で逆順で sort してくれるので、最後にくっつけるとものによっては見やすくなります。

$ netstat -tn | awk '{print $6}' | sort | uniq -c | sort -nr
     31 ESTABLISHED
      1 状態
      1 TIME_WAIT
      1 CLOSE_WAIT
      1

欲しい行だけ抜き出す

grep とか egrep とか使えばいいですね。圧縮展開が面倒だ、というときには zgrep とか zegrep とかもあります。あんまり option 覚えていませんが、良く(?)使うのは

option 説明
-i 大文字小文字区別しない
-v マッチする行以外を表示
-a ascii として grep (制御文字入っちゃってるときとか)
-h 複数ファイル指定したとき行頭にファイル名を入れない

少ないな、覚えてるの。表組する程でもないかもしれない。

行のうち欲しい部分だけ抜き出す

上にも出てるけど手軽なのは awk$6 とかしてスペースとか区切りの文字を抜き出してしまう方法。若しくは cut-c で抜き出す column を指定しても良い。

$ sudo cut -c -9 /var/log/messages* | uniq -c | sort -n | tail
      9 Mar 29 20
      9 Mar 30 02
     10 Mar  9 08
     10 Mar 18 01
     10 Mar 20 01
     17 Mar 30 00
     27 Mar 12 01
    225 Mar 29 19
    351 Mar 13 07
   9118 Mar 18 23

ちなみに、3/18 の 23:43 は OOM killer が走っていました。

気軽に Perl に手を出す

awk 力が高かったり grep 力が高かったりすると色々できそうですが、私の場合貧弱なので直ぐに Perl に手を出します。

perl-n で引数で指定されたファイルや標準入力の各行を $_ という変数に入れて各行を処理してくれます。処理内容は -e でしてあげれば ok です。

$ netstat -tn | perl -ne '@F=split(" "); print $F[5]."\n";' | sort | uniq -c
      1
      2 CLOSE_WAIT
     28 ESTABLISHED
      1 TIME_WAIT
      1 状態

これは awk と同じことをやってるんですが、-a を付けると awk っぽく振る舞ってくれるようになり @F の定義すら必要なくなります。

$ netstat -tn | perl -a -ne 'print $F[5]."\n";' | sort | uniq -c
      1
      2 CLOSE_WAIT
     28 ESTABLISHED
      1 TIME_WAIT
      1 状態

また、-F で区切り文字も色々変えれます。-F, とかすればお手軽な CSV であれば読めます。で、これでもぉ立派な Perl なので、"Foreign Address" が 443 port のものの "State" だけ出力、というのも簡単にできます。

$ netstat -tn | perl -ane 'print $F[5]."\n" if $F[4] =~ /:443/;' | sort | uniq -c
      6 ESTABLISHED
      1 TIME_WAIT

正規表現さえ使えてしまうと、例えば URL っぽいものを全部引っこ抜くというのも簡単です。

$ curl -s http://www.google.com/ | perl -ne 'while (s/href="(http[^"]+)"//) { print $1."\n" }' | less
http://www.google.com/imghp?hl=en&tab=wi
http://maps.google.com/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?tab=w1
http://news.google.com/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
http://www.google.com/intl/en/options/
http://www.google.com/history/optout?hl=en
https://accounts.google.com/ServiceLogin?hl=en&continue=http://www.google.com/
https://plus.google.com/116899029375914044550

足し算したい

awk を使った場合は END を使うとファイル読み込みの最後の処理を指示できます。ps aux の結果から RSS の合計を得るには

$ ps aux  | awk '{s+=$6} END {print s}'
6787580

s が自動的に 0 に初期化されて後は足されていきます。

繰り返す

zsh を全く使いこなしていないので未だに for 文を書いています。bash すら使いこなしていません。

for i in `seq -w 2 3 20`; do echo $i; done
02
05
08
11
14
17
20

これは 2 から 20 まで 3 ずつ増やして 0 詰の等幅で表示しています。echo を wget にしたりすると連番ゲットだぜ的なものになります。

$ for i in `seq -w 2 3 20`; do wget http://www.example.com/$i.png; done

これは Perl で URL っぽいものを引っこ抜き続けるのも同じです。`` で囲まれてる部分がだんだん長くなってくると、残念な気分が増してきます。mysql とか入れないようにしましょう。

再帰的に directory を掘る

未だに ackag を使っていない老害です。findxargs を使っています。zsh があればここにあることは不要なはずです。あんまり参考にせず zsh とか使いこなしましょう。

近頃の find は何も引数つけないと -print と同じでファイルなどの名前を表示してくれます。GNU と FreeBSD とかの違いかもしれません。

find /usr/lib/python2.7 | head -n 5
/usr/lib/python2.7
/usr/lib/python2.7/nntplib.pyc
/usr/lib/python2.7/dbhash.py
/usr/lib/python2.7/inspect.pyc
/usr/lib/python2.7/textwrap.pyc

'-name' すると名前を絞ってくれます。例えば *py にマッチするものだけなら、

find /usr/lib/python2.7 -name '*py'| head -n 5
/usr/lib/python2.7/dbhash.py
/usr/lib/python2.7/_weakrefset.py
/usr/lib/python2.7/commands.py
/usr/lib/python2.7/mailbox.py
/usr/lib/python2.7/os.py

で、xargs で出てきた出力結果ファイルに一斉にコマンドを実行します

$ find /usr/lib/python2.6/site-packages/botocore -name '*py' | xargs egrep 'request\.'  | less
/usr/lib/python2.6/site-packages/botocore/operation.py:        in a request.
/usr/lib/python2.6/site-packages/botocore/awsrequest.py:    """Represents a prepared request.
/usr/lib/python2.6/site-packages/botocore/response.py:        # the request.
/usr/lib/python2.6/site-packages/botocore/response.py:    if not http_response.request.method == 'HEAD':
/usr/lib/python2.6/site-packages/botocore/retryhandler.py:            to send the request.
(snip)

これは、指定したフォルダ以下の py で終わるファイルで request という変数の attribute を参照している部分を探していますね。何したかったんだろう。。。

findxargs の組み合わせは、ファイル名に space が入ってたりすると悲惨なことになるので find-print0xargs-0 を組み合わせる必要がありますが、まぁ、ぐぐってみて下さい。

find-type でファイルタイプが指定できますが大抵 -type f で regular file に限定する程度でしょう。-mtime -3 とかで過去 3 日以内に変更されたファイル、なども選べるので、/var/log で作業するときには少し便利かもしれません。

証明書をゲットしたい

www.google.com のサーバ証明書だけ欲しい場合には以下で google.pem に保存できます。

$ openssl s_client -connect www.google.com:443 < /dev/null | openssl x509 > google.pem

中身にしか興味が無い場合には、さっさと parse しちゃいます。

$ openssl s_client -connect www.google.com:443 < /dev/null | openssl x509 -noout -text | less
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 8151063296760904526 (0x711e64e1d9287b4e)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, O=Google Inc, CN=Google Internet Authority G2
        Validity
(snip)

負荷分散されてる場合とか、一遍に調べたい場合には for で回しちゃいましょう。openssl-servername は、対応してたら使えるといいですね!!

$ for i in `dig +short www.google.com`; do openssl s_client -servername www.google.com -connect $i:443 < /dev/null > $i.pem;done
$ ls
173.194.33.48.pem  173.194.33.49.pem  173.194.33.50.pem  173.194.33.51.pem  173.194.33.52.pem

JSON が返ってくるんですけど

perl でよければ URL っぽいもの引っこ抜く奴で正規表現で頑張れます。あと、json_pp ってコマンドもあって、これ使うと pretty print してくれるので grep とかできますね。

python 使うと json モジュールを呼び出して parse できます。

$ python -m json.tools < cfn.template

まぁ、素直に jq 使え、という話な気がしてきます。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11