发新话题
打印

[教程] 10のUNIX小技

10のUNIX小技

1. ディレクトリの作成
良く使うコマンドの一つであるmkdirですが、面倒臭い使い方をしていませんか?

悪い例

~/ $ mkdir a
~/ $ cd a
~/a $ mkdir b
~/a $ cd b
~/a/b/ $ mkdir c
~/a/b/ $ cd c
~/a/b/c $
良い例

mkdir -p a/b/c
良い例2:複雑な構造をコマンド一発で作る例

mkdir -p a/{lib,src,doc/{html,pdf,txt}}
mkdirに-pオプションがない場合
mkdirhierを使うと同様の事ができるそうです。


mkdirhier -p a/{lib,src,doc/{html,pdf,txt}}


2. tarの解凍先を指定する
tarを解凍するために目的のディレクトリまでtarファイルを移動するのも悪い慣習の一つです。 tarの-Cオプションを使えば好きなディレクトリへtarファイルを解凍できます。


tar xfv a.tar -C /tmp/a/b

-Cオプションを使う方法は、tarファイルを移動して、cdでディレクトリを移動して、tarコマンドで解凍をするやり方よりも推奨されます。特に、アーカイブファイルが自分ではない誰かのものである場合には。



3. コマンドを演算子で繋げる
「;」を使って複数のコマンドを1行で繋げられる事は知っていると思います。これは複数のコマンドを実行するには便利ですが、万能ではありません。例えば、「;」を使って2つのコマンドを実行するとします。二つ目のコマンドが一つ目のコマンドに依存する場合、一つ目のコマンドが失敗した場合には、二つ目のコマンドは必ず失敗します。そのような場合には「;」ではなく、より適切な演算子を使うと良いでしょう。

一つ目のコマンドが成功した(return 0)場合にだけ実行

cd tmp/a/b/c && tar xvf ~/archive.tar

一つ目のコマンドが失敗した(return 0以外)場合にだけ実行

cd tmp/a/b/c || mkdir -p tmp/a/b/c


cd tmp/a/b || mkdir -p tmp/a/b && tar xvf -C tmp/a/b ~/a.tar



4. 変数と「"」の組み合わせは慎重に
特別な理由が無い限り、変数は「"」で囲う方が良いでしょう。もし、変数名の直後に文字を使いたいのであれば、変数名を「{}」で囲いましょう。これを忘れてしまうと、別の変数名として扱われてしまいます。意図しない別の変数名になってしまった場合、大抵はnull値になるでしょう。


$ ls tmp/
a b
$ VAR="tmp/*"
$ echo $VAR
tmp/a tmp/b
$ echo "$VAR"
tmp/*
$ echo $VARa

$ echo "$VARa"

$ echo "${VAR}a"
tmp/*a
$ echo ${VAR}a
tmp/a
$



5. 長い入力にはエスケープシーケンスを利用
シェルスクリプト内で長いコマンドを表すために「\」が使われているを見た事がある人は多いと思われます。しかし、手でコマンドを打つときに「\」を使う人は意外に少ないのではないでしょうか。「\」を使って単一の行を複数行に分けて入力する方式は、ターミナルが複数行へのwrappingに対応していないときに便利です。


$ cd tmp/a/b/c || \
> mkdir -p tmp/a/b/c && \
> tar xvf -C tmp/a/b/c ~/archive.tar


$ cd tmp/a/b/c \
>                 || \
> mkdir -p tmp/a/b/c \
>                    && \
> tar xvf -C tmp/a/b/c ~/archive.tar

(注意) 大抵のshellでは、上矢印などで履歴を利用すると複数行で入力したコマンドであっても1行として出てきてしまいます。



6. コマンドをグループ分けする
大抵のシェルには、コマンドをグループ分けして実行する機能を持っています。一般的には、subshellで行う方法と、現在実行しているshellで行う2通りの方法があります。

subshell
subshellを使う方法は、環境変数を定義しなおしたい場合に有効です。 subshellで環境変数を変更しても、現在実行中のshellが保持する環境変数は維持されます。


$ ( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c && \
> VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar ) \
> | mailx admin -S "Archive contents"

現在のshell
「{}」の前後にスペースが入るように注意しましょう。スペースを入れないと正しく動作しないかも知れません。

また、「}」の前に来る最後のコマンドの後に「;」を入れるのを忘れないようにしましょう。


$ { cp ${VAR}a . && chown -R guest.guest a && \
> tar cvf newarchive.tar a; } | mailx admin -S "New archive"



7. xargsをfind以外と組み合わせる
xargsはfindが出力するファイル名を使って他のコマンドを実行するために使われます。例えば、以下のようにfindが発見したファイル名をxargsに渡して処理をさせます。


$ find  何か  どこかへのパス | \
> xargs ファイル名を使う何らかのコマンド

しかし、xargsは単なるfindの補助ツールではありません。

利用例

$ xargs
a
b
c
コントロールキー+p
a b c

ファイル名を出力する他のコマンドと組み合わせる事も可能です。


$ ls | xargs
December_Report.pdf README a archive.tar mkdirhier.sh
$ ls | xargs file
December_Report.pdf: PDF document, version 1.3
README: ASCII text
a: directory
archive.tar: POSIX tar archive
mkdirhier.sh: Bourne shell script text executable

複数行を一行にまとめる事も出来ます。


$ ls -l | xargs
-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1 \
root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02 \
16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1 \
joe joe 3239 Sep 30 12:40 mkdirhier.sh

xargs利用上の注意
「_(アンダースコア、下棒)」はEOFとして扱われます。そのため、その文字がxargsに渡されると、それ以降の項目は無視されてしまいます。この問題を回避するには-eオプションを利用してください。



8. grepに行数をカウントさせる
wc -l と組み合わせるのではなく、grep の-cオプションを使った方が行数の計算は速いです。


$ time grep PATTERN longfile.txt | wc -l
2811

real    0m0.097s
user    0m0.006s
sys     0m0.032s
$ time grep -c PATTERN longfile.txt
2811

real    0m0.013s
user    0m0.006s
sys     0m0.005s

grepがカウントすべきではないとき
-cオプションは、マッチした行数のみをカウントします。 -oオプションは、マッチしたパターン自体を出力します。単一行にマッチするパターンが複数回登場する時などには、-oオプションにより標準出力に出される行数と、-c が行った結果のカウント数が異なってしまいます。そのような場合には、wc -l を使いましょう。


grep -o PATTERN longfile.txt | wc -l



9. パターンマッチは行全体ではなくフィールドで
grepなどで行全体をマッチするのではなく、awkで特定のフィールドを指定してパターンマッチをすべきです。

grepで行全体をマッチさせてしまうと、意図しないものも結果に入ってしまうことがあります。例えば、ファイル更新日が12月のものを探している時に、1月に更新したDecemberReport.pdfが結果に入ってしまう場合があります。

悪い例

ls -l | grep Dec
-rw-r--r--  7 joe joe  12043 Jan 27 20:36 December_Report.pdf
-rw-r--r--  1 root root  238 Dec 03 08:19 README
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
良い例

ls -l | awk '$6 == "Dec"'
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
-rw-r--r--  1 root root  238 Dec 03 08:19 README


10. 無駄なcatとパイプは行わない
grepなどのコマンドを使う時に、catをパイプで繋げてgrepの標準入力に流し込むのは無駄です。 grepなどの大抵のコマンドには、ファイル名をオプションとして渡せる機能があります。以下に速度の比較を示します。


$ time cat longfile.txt | grep PATTERN
2811

real    0m0.015s
user    0m0.003s
sys     0m0.013s

$ time grep PATTERN longfile.txt
2811

real    0m0.010s
user    0m0.006s
sys     0m0.004s
Life is like a box of chocolates: you never know what you're gonna get.

TOP

这牛啊,我就是那个悪い例
离开毛茸茸的状态,死挺,成为社会中坚。

TOP

共勉共勉
Life is like a box of chocolates: you never know what you're gonna get.

TOP

windows底下怎么建一堆目录?
离开毛茸茸的状态,死挺,成为社会中坚。

TOP

一样的吧,试了一下:
C:\Documents and Settings\Administrator>mkdir -p/?
ディレクトリを作成します。

MKDIR [ドライブ:]パス
MD [ドライブ:]パス

コマンド拡張機能を有効にすると、MKDIR は次のように変更されます:

MKDIR は、必要に応じてパスの中間ディレクトリを作成します。
たとえば、\a が存在しない場合、

    mkdir \a\b\c\d

は、次と同じです:

    mkdir \a
    chdir \a
    mkdir b
    chdir b
    mkdir c
    chdir c
    mkdir d

拡張機能が無効な場合は、上のように入力します。

Windows2000 以前的版本可不可以用就不知道了
花开花落

TOP

ありがとう!
离开毛茸茸的状态,死挺,成为社会中坚。

TOP

那个 -p 是什么意思(^^;;?
花开花落

TOP

回复 #5 JoJo 的帖子

编成一个bat文件,リリース的时候很方便。

TOP

发新话题