末尾ひとつ前のフィールドを取得

`awk`で表題の通り。

■ 環境

  • awk 3.1.7
  • CentOS 6.7

■ awk

`awk`で末尾のフィールドの値を取得することがある。例えば下記のようなCSVである場合。

$ cat test.csv
1,aaa,bbb,ccc
2,aiueo,aiueo,aiueo
3,test1,test2,test3
$
$ awk -F, '{print $NF}'
ccc
aiueo
test3
$

フィールド数を取得できる”NF“と”$“で末尾の値を取得している。フィールド数がそれほどなければ末尾ひとつ前のフィールドの値もわかりやすいが、これ何番目だ?と数えるのが億劫な場合は下記で取得することができる。

$ awk -F, '{print $(NF-1)}' test.csv
bbb
aiueo
test2
$

以上。

shuf

表題のコマンドを知ったのでメモ。

■ 環境

  • Amazon Linux

■ shuf

どのパッケージに入っているのか確認。

$ which shuf
/usr/bin/shuf
$ rpm -qf /usr/bin/shuf
coreutils-8.22-15.52.amzn1.x86_64
$

ヘルプを見てみる。

$ shuf --help
使用法: shuf [OPTION]... [FILE]
または: shuf -e [OPTION]... [ARG]...
または: shuf -i LO-HI [OPTION]...
Write a random permutation of the input lines to standard output.

Mandatory arguments to long options are mandatory for short options too.
  -e, --echo                treat each ARG as an input line
  -i, --input-range=LO-HI   treat each number LO through HI as an input line
  -n, --head-count=COUNT    output at most COUNT lines
  -o, --output=FILE         write result to FILE instead of standard output
      --random-source=FILE  get random bytes from FILE
  -r, --repeat              output lines can be repeated
  -z, --zero-terminated     end lines with 0 byte, not newline
      --help     この使い方を表示して終了する
      --version  バージョン情報を表示して終了する

ファイルの指定がなかったり, - であった場合, 標準入力から読み込みます.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
shuf の翻訳に関するバグは <http://translationproject.org/team/ja.html> に連絡してください。
完全な文書を参照する場合は info coreutils 'shuf invocation' を実行してください。
$

実際に試してみる。10から20の間の数をシャッフルする。

$ shuf -i 10-20
13
17
20
10
15
12
18
14
11
19
16
$

なるほど。ではこの中から1つを表示。

$ shuf -i 10-20 -n 1
14
$ shuf -i 10-20 -n 1
19
$ shuf -i 10-20 -n 1
11
$

実行する毎にランダムにシャッフルした結果の1つを取得できる。単純にランダムな数値を欲しい時に使えそうだ。

以上。

ncでport開放チェック

表題の通り。『初めてのAnsible』を読んでる中で知ったのでメモ。

■ 環境

  • Amazon Linux
  • Ubuntu 16.04

■ nc

ZooKeeperの4文字コマンドとかで使っていたが、こういう使い方もあるようだ。『初めてのAnsible』には下記のように書かれていた。

$ nc -z -w $time $host $port

実際にやってみると下記のように得られた。

$ nc -z -w 1 192.168.33.11 22
Connection to 192.168.33.11 22 port [tcp/ssh] succeeded!
$
$ nc -z -w 1 192.168.33.11 80
Connection to 10.1.1.101 80 port [tcp/http] succeeded!
$
$ nc -z -w 1 192.168.33.11 443
$

22“の”SSH“と、”80“の”HTTP”は確かに開いているので”succeeded“で正しい。”443“の”HTTPS“は開いていないので何も得られなかった。この時の戻り値は”1“であった。これはまた使えそうである。

以上。

■ 関連

GeoIP on Ubuntu

表題の通り。UbuntuでGeoIPを使いたい。

■ 環境

  • Ubuntu 14.04

■ GeoIP

まずは検索。

$ sudo apt-cache search geoip
  :
geoip-bin - IP lookup command line tools that use the GeoIP library
geoip-database - IP lookup command line tools that use the GeoIP library (country database)
geoip-dbg - debugging symbols for the GeoIP packages
  :
$

この辺りであろうか。

$ sudo apt-get install geoip-bin

何がインストールされたのか確認。

$ dpkg -L geoip-bin
/.
/usr
/usr/lib
/usr/lib/geoip
/usr/lib/geoip/geoip-generator
/usr/lib/geoip/v4-to-v6-layout.pl
/usr/share
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/geoiplookup6.1.gz
/usr/share/man/man1/geoiplookup.1.gz
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/geoip-bin
/usr/share/doc
/usr/share/doc/geoip-bin
/usr/share/doc/geoip-bin/copyright
/usr/bin
/usr/bin/geoiplookup
/usr/bin/geoiplookup6
/usr/share/doc/geoip-bin/changelog.Debian.gz
$

`geoiplookup`がインストールされているのでとりあえずはこれで良いだろう。”GeoIP.dat“が無いので、いつの時点のものになるのだろうか?それとも外部にアクセスしにいっているのだろうか。”geoip-database“というパッケージもあるのでそれが怪しそうである。

とりあえずはやりたいことができたので終了。

以上。

■ 関連

cronでの%をエスケープ

表題の件について。久しぶりになんだっけこれ?とハマったのでメモ。

■ 環境

  • Ubuntu 16.04

■ cron

`cron`で実行されるジョブの中で`date`で日付を入れた処理をいれたらうまく実行してくれなかった。例えば下記のような感じのジョブとする。

crontab -l
0 1 * * * touch /tmp/`date --date '-1 day' +'%Y%m%d'`.txt
$

これは失敗する。下記のようなメールが飛んでいた。

/bin/sh: 1: Syntax error: EOF in backquote substitution

`date`等の”%“はエスケープする必要がある。下記のように書かなければならない。

crontab -l
0 1 * * * touch /tmp/`date --date '-1 day' +'\%Y\%m\%d'`.txt
$

なんかいつも同じ間違いをしている気がするので自戒のためにメモ。

以上。