ShellScript
Linux

実務で役立つシェル系Tips

More than 1 year has passed since last update.

パスの末尾に/があるかないかを気にしたくない

文字列を結合してパスを生成したりするときに、パスを格納した複数の変数を文字列結合するときがあります。

dirHome="/var/lib/hoge/"
workDirName="work"

echo "${dirHome}${workDirName}"  # /var/lib/hoge/workと表示される

しかし、dirHomeworkDirNameのような変数をコンフィグファイルで設定していたり、実際に参照するところと定義箇所が遠いときがあると厄介なことが起こりえます。

例えば、下記のようにdirHomeの末尾に/がなかったらどうなりますでしょうか?

dirHome="/var/lib/hoge"
workDirName="work"

echo "${dirHome}${workDirName}" #/var/lib/hogeworkと表示されてしまう

これを防ぐ方法があります。

${dirHome%/}/${workDirName}

%Xはその前の変数に含まれる文字列を末尾からXを検索して最も近くでヒットしたXを削除します。
この%/の場合、末尾に/のあるパターンの/を削除します。
そのため、${dirHome}の末尾に/があるかないかを問わず、常に/を末尾に追記することができます。
ちなみに、最も最後にヒットしたXを削除する%%Xも存在します。

プロセスの検索にはpgrepを使う

pgrepが使える環境であれば、それを使うようにしましょう。
pgrep hogeと記述すれば、下記のようなコマンドを打つ必要がなくなります。

ps -ef | grep -v grep | grep hoge

0でpaddingされた連番のファイルを作りたい

printfのようにフォーマットを指定して連番を作ることが可能です。

seq -f "hoge%03g.txt" 3

# 下記が表示される
# hoge001.txt
# hoge002.txt
# hoge003.txt

(※seqは内部で数値を実数として扱っているためdフォーマット指定子は使用できません)

-wオプションもありますが、-fの方が汎用的なので、そちらを使った方がわかりやすいかと思います。

文字列はクォートで囲うようにする

変数の定義の仕方は3通りあります。

var=HOGE
var='HOGE'
var="HOGE"

格納する文字列にスペースが入っていたり、エディタのシンタックスハイライトのことを考えると、クォートで囲うようにしたほうが良いでしょう。

ファイル名に実行した日付を入れたい

ls -la > _result_`date +"%Y%m%d-%H%M%S"`.txt

フォーマットの記述が覚えづらいかもしれませんが、「月と日以外は大文字」でフォ−マットの指定の仕方を覚えると良いでしょう。

数値計算には$(())を使うようにする

数値計算の記述の方法が2種類あります。

ans=$((1 + 1))
ans=`expr 1 + 1`

しかしながら、$(())を使うようにしたほうがよいでしょう。
exprは掛け算と割り算に関してエスケープが必要であったり直感的でありません。

ans=`expr 2 \* 1`
ans=`expr 2 \/ 1`

検索したファイル名とファイル名称とファイルサイズを獲得したい

find . -ls -print | awk '{ print $11 " "  $7}'

findコマンドに-lsをつけるとls -lをしたときのようにファイルのメタ情報が見られるようになるのですが、それらは列表示されています。そしてそれらをawkコマンドに渡すことで$11のようにしてカラム番号を指定してカラムを獲得することができます。

ファイルサイズを物理サイズで獲得したい

duコマンドはブロックサイズでサイズを計算します。
そのためduコマンドでは物理サイズを獲得することができません。
find -lsコマンドを使用します。

find . -ls | awk '{ print $11 " "  $7}' 

# ./hogehoge.txt 430620 と表示される

なお、ディレクトリサイズはコピーしたときに減ることがあります。
これはディレクトリにファイルを格納していくとディレクトリのブロックサイズも増えていくのですが、その後にファイルを削除してもブロックサイズは縮小されないためです。

コマンドの結果から複数の特定のワードが含まれないもののみを出力するようにする

grepコマンドの-vオプションを指定すると、指定したワードを除外してgrepすることができます。
しかしながら、複数ワードの除外ワードを指定したい場合、

grep -v hoge | grep -v hoge2

などと、パイプでつないでいくのは冗長になってしまいます。

grepには複数のワードを指定するためのオプションが用意されています。

grep -v -e hoge -e hoge2

-e [ワード]を複数記述することで複数ワードを記述することができるようになります。

これを応用すれば、下記のようなことも可能になります。

## コメントと空行を除いてファイル行数をカウントする
cat hoge.txt | grep -v -e '^\s*#' -e '^\s*$' | wc -l

findしたファイルリストをソートしたい

ls -lt `find /var -name *.txt -type f -print`

上記の場合、上から下に、新しい順に表示されます

findする時にPermission deniedのものを排除する

find . 2>/dev/null

エラーがあったときに処理を中断する

#!/bin/bash
set -e