モノノフ日記

普通の日記です

シェルスクリプトノウハウ part2

IBM DeveloperWorksにTipsの続編があったのでまとめておきます。コマンド履歴、pushd・popd、awkは覚えると便利です!

ファイル名の補完

どのシェルで動いているかチェック
$ echo $0
-zsh
$ ps -p $$
  PID   TTY        TIME CMD
18805 pts/0    00:00:06 zsh
C Shell
set filec

上記コマンドでファイル補完がONになる。ESCキーでファイル補完。

Bash

Tabで補完

Korn Shell

指定している標準エディタで方法が異なる。

EDITOR 補完コマンド
vi ESC->バックスラッシュで補完
emacs ESCキー2回押しで補完

コマンド履歴の活用

!$は1つ前のコマンドの最後のフィールドに書いたものを返してくれます。大抵ファイル名になりますね。

$ grep pickles this-is-a-long-lunch-menu-file.txt
pastrami on rye with pickles and onions
$ vi !$

1つ前の引数の再利用法

!:1で1つの前のコマンドの第1引数にアクセスできます。$:2なら第2引数。

$ mv kxp12.c file_system_access.c
$ ln –s !$ !:1

pushdとpopdを使ったディレクトリ移動

pushdとpopdを使うと、バーチャルディレクトリスタックを作った移動が可能になります。dirsを使うと現在スタックしているディレクトリ一覧が見れます。

  • pushd
    • 現在のディレクトリをスタックに入れて、指定先へ移動
  • popd
    • スタックの先頭のディレクトリを出して、そこへ移動
$ pushd .
~ ~
$ pushd /etc
/etc ~ ~
$ pushd /var
/var /etc ~ ~
$ pushd /usr/local/bin
/usr/local/bin /var /etc ~ ~
$ dirs
/usr/local/bin /var /etc ~ ~
$ popd
/var /etc ~ ~
$ popd
/etc ~ ~
$ popd
~ ~
$ popd

pushd、popd共にスタック操作するパラメータをサポートしていて、+n、-nと数字を与えることでスタックを右、左へローテーションできます。

$ dirs
/usr/local/bin /var /etc ~ ~
$ pushd +1
/var /etc ~ ~ /usr/local/bin
$ pushd -1
~ /usr/local/bin /var /etc ~

サイズの大きいファイルの見つけ方

dfでディスク容量のチェック。-hオプション使うと視認しやすくなります。

$ df
Filesystem                            512-blocks      Used  Available Capacity  Mounted on
/dev/disk0s2                           311909984 267275264   44122720    86%    /
devfs                                        224       224          0   100%    /dev
fdesc                                          2         2          0   100%    /dev
map -hosts                                     0         0          0   100%    /net
map auto_home                                  0         0          0   100%    /home

find使ってサイズが10M以上のファイルを見つけるサンプル

$ find / -size +10000k -xdev -exec ls -lh {}\; 

エディタ無しでtmpファイルの作成

catと>オペレータ使うとエディタ無しでファイルに書き込む。終了する場合はCtrl+D

$ cat > my_temp_file.txt
This is my temp file text
^D
$ cat my_temp_file.txt
This is my temp file text

catと>>オペレータだと追記モード

$ cat >> my_temp_file.txt
More text
^D
$ cat my_temp_file.txt
This is my temp file text
More text

curlコマンドの使い方

サンプルはNational Weather ServiceからBUFFALOの天気予報を取得

$ curl -s http://www.srh.noaa.gov/data/ALY/RWRALY | grep BUFFALO
BUFFALO MOSUNNY 43 22 43 NE13 30.10R 

ファイルダウンロードする場合は-oオプション

$ curl -o archive.tar http://www.somesite.com/archive.tar

正規表現

参考ページの表をそのまま持ってきました。
?が行末表現になってるけど、$じゃないのかな?サンプルコードは$使ってます。

シーケンス 説明
Caret (^) 行頭にマッチ
Question mark (?) 行末にマッチ(?
Backslash (\) 次の文字をそのまま表示
Brackets ([]) []内に含まれる文字にマッチ。範囲指定表現も可
[^ ] []内に含まれない文字にマッチ。範囲指定表現も可
Period (.) 行末を除く任意の1文字にマッチ
Asterisk (*) 0回以上の表現の繰り返し
\{x,y\} x回以上y回以下の繰り返し
\{x\} x回の繰り返し
\{x,\} x回以上の繰り返し

実行サンプル

$ # 自分へのメールをリスト
$ grep '^From: ' /usr/mail/$USER   
$ # 英文字を含む行  
$ grep '[a-zA-Z]'  search-file.txt
$ # 英文字と数字を含まない行
$ grep '[^a-zA-Z0-9] search-file.txt
$ # 999-9999のような形式の電話番号
$ grep '[0-9]\{3\}-[0-9]\{4\}' search-file.txt
$ # 1文字のみの行
$ grep '^.$' search-file.txt
$ # ピリオドで始まってる行
$ grep '^\.' search-file.txt
$ # ピリオドで始まって、その後ろに英小文字が2つ続く行
$ grep '^\.[a-z][a-z]' search-file.txt

カレントユーザの確定

whoamiでカレントユーザが返ってくる。サンプルはユーザ判定に利用。

if [ $(whoami) = "root" ]
then
   echo "You cannot run this script as root."
   exit 1
fi

awkの使い方

参考リンク先に「The awk command always seems to live in the shadows of Perl」と書かれてるawkですが使えるとテキスト整形には便利です。

length()とindex()とsplit()のサンプル
$ cat text
testing the awk command
$ awk '{ i = length($0); print i }' text
23
$ awk '{ i = index($0,ing); print i}' text
5
$ awk 'BEGIN { i = 1 } { n = split($0,a," "); while (i <= n) {print a[i]; i++;} }' text
testing 
the
awk
command
カンマ区切りのデータ収集サンプル
$cat sales
Gene,12,23,7
Dawn,10,25,15
Renee,15,13,18
David,8,21,17
$ awk -F, '{print $1,$2+$3+$4}' sales
Gene 42
Dawn 50
Renee 46
David 46