パスの末尾に/
があるかないかを気にしたくない
文字列を結合してパスを生成したりするときに、パスを格納した複数の変数を文字列結合するときがあります。
dirHome="/var/lib/hoge/"
workDirName="work"
echo "${dirHome}${workDirName}" # /var/lib/hoge/workと表示される
しかし、dirHome
やworkDirName
のような変数をコンフィグファイルで設定していたり、実際に参照するところと定義箇所が遠いときがあると厄介なことが起こりえます。
例えば、下記のように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