Cygwinの基礎の基礎


Cygwin

コマンド苦手が時々使うCygwinのコマンドとサンプル。

はじめに

CygwinとはWindows上でUNIXのコマンドを使えるようにするツールである。
(もしかすると今はPower Shellでも同等のことができるのかもしれないが、Power Shellは試してない。)

CygwinはCUI、つまり文字でPCを操作するインタフェースだが、基本的な考え方はGUIと変わらない。現在開いているディレクトリがあり、そこから目的のディレクトリに移動して、ファイルを開いて作業をする。もちろん、GUI同様に、現在開いているディレクトリから移動せずに作業もできる。

準備

インストール

Cygwin Installationのsetup.exeをダウンロードしてインストール。インストール後は、スタートメニューの [Cygwin] - [Cygwin Bash Shell] から起動。

設定

Cygwinディレクトリのルートは「cygdrive」だが、設定で「cygdrive」を入力しなくてよいように変更可能。
C:\cygwin\etc\fstab の5行あたりを以下のように変更する。

変更前: # none /cygdrive cygdrive binary,posix=0,user 0 0
変更後: none / cygdrive binary,posix=0,user 0 0

上記の変更をすると、cd /cygdrive/c/xampp/ではなくcd /c/xampp/でOKになる。

基本的なコマンド

コマンド 挙動
cd ディレクトリ移動 cd /c/xampp/
exit 終了 exit
ls 現在のディレクトリ以下を検索 ls */image/
find 検索。「-o」で条件をつなげられる。 find . -name '*.html'
grep 正規表現を使用した検索。「-i」で大文字小文字区別しない。「-L」でその文字を含まない。 grep -i 'utf-8' index.html
wc カウント。「wc -l」で行数を数える。 wc -l
> 結果をファイルに出力 (同名ファイルがあれば上書き)。他のコマンドと合わせて使う。 ls > foo.txt
>> 結果をファイルに出力 (同名ファイルがあれば追加)。他のコマンドと合わせて使う。 ls >> foo.txt
| 結果を別コマンドに渡す。 ls | wc -l

組み合わせ

HTMLファイルの一覧を作成

$ find . -name "*.html" > ../list.txt

ファイルの一覧を作成

「dirA」ディレクトリを除外し、全ファイル一覧を作成する場合。

$ find . -type d -name dirA -prune -o -print > ../list.txt

拡張子一覧を作成

$ find . -type f | while read i
> do
> echo ${i##*.}
> done | sort | uniq > ../list.txt

「gtm.js」という文字列が入っていないHTMLファイル一覧を作成

$ find . -name '*.html' | while read i
> do grep -L 'gtm.js' $i
> done > ../list.txt

Shift_JISのHTMLファイル数をとる

$ find . -name '*.html' | while read i
> do nkf -g $i
> done | grep -i shift_jis | wc -l

ディレクトリ内の差分をとる

「dirA/subDir/」「dirB/subDir/」ディレクトリ除く。

$ diff -qr dirA dirB --exclude=subDir > ../list.txt

SVN管理されているバックアップファイルと思われるファイルを削除

拡張子をいくつか決め打ち + 「xxx.拡張子.xxx」というファイル名の場合。確実にバックアップという保証はないのでコミット前に精査が必要。

$ find \( -name '*.html.*' -o -name '*.css.*' -o -name '*.js.*' -o -name '*.gif.*' -o -name '*.jpe?g.*' -o -name '*.png.*' \) | while read i
> do svn delete $i
> done

「拡張子以降に数字が入っている」場合。確実にバックアップという保証はないのでコミット前に精査が必要。上のよりは精度が高い。

$ find -regex '.*\..+?\.[A-Za-z_]*[0-9]+[A-Za-z_]*' | while read i
> do svn delete $i
> done

改行コードの一覧を表示する

$ find . -name "*.html" | while read i
> do file $i >> ../list.txt
> done

ディレクトリ内の全HTMLをLF → CR+LFに置換

$ find . -name "*.html" | xargs unix2dos

ディレクトリ内の全HTMLをUTF-8に置換

$ find . -name '*.html' | while read i
> do nkf -w --overwrite $i
> done

同じファイルを大量にコピー

作りたいファイル名の一覧 output.txt を読み込んで _template.html を元に複製。output.txt は、1行 = 1ファイル名。

$ cat output.txt | while read i
> do
> cp -f ./_template.html $i
> done

特定の拡張子のファイルを別ディレクトリにコピー

「dirA」ディレクトリ以下からPDFファイルを見つけ出し、階層構造は保ったまま「dirB」ディレクトリ配下にコピー。

$ find dirA -name '*.pdf' | while read i
> do
> mkdir -p dirB/`dirname $i`
> cp $i dirB/`dirname $i`
> done

階層構造は以下のようなものを想定。

dirA
├ aaa
│ ├ 1.pdf
│ ├ 2.pdf
│ └ 3.txt
├ bbb
│ ├ 4.pdf
│ ├ 5.txt
  • while read i... はwhile文になり、>で繰り返す内容を記述できる。
    • $iにはfindの検索結果が順に入る。
    • 上記のような構造のとき、$iは「aaa/1.pdf」「aaa/2.pdf」「bbb/4.pdf」になる。
  • cp はディレクトリが存在しないとエラーになるため、コピー先のディレクトリをmkdirで作成してから cp
  • 作成するディレクトリ名はdirnameで取得する。