ファイルに対する操作

サルの知恵袋

  • ファイル編 -

[目次(I)] [ファイル] [ディレクトリ(D)] [Shell(S)] [ジョブ(J)] [Emacs(E)] [ネットワーク(N)] [その他(O)] [トラブル(T)] [MacUNIX(M)] [UNIX 管理(A)] [番外編(X)]
ファイルに対する操作

1. ファイルの中身を表示したい
2. ファイルを編集したい
3. ファイルの名前を変更したい
4. ファイルを移動させたい
5. ファイルをコピーしたい
6. ファイルを消したい
7. ファイルを圧縮したい
8. ファイルを探したい
9. ファイルの大きさを知りたい
10. ファイルの中から文字を探したい
11. ファイルの中の文字列を置換したい
12. 2つのファイルの中身を比較したい
13. 2つのファイルをひとつにくっつけたい
14. ファイルの改行コードを変換したい
15. 圧縮されたファイルの中身を展開せずに知りたい

ファイルに対する操作

1.
ファイルの中身を表示したい
ファイルの中身を表示する方法はいくつかあります。例えば "file" というファイルを表示するとしましょう。それには次のような cat, more, less という UNIX コマンドのうちのどれかが使えます。

cat file
more file
less file

この3つのどれでもファイルの中身を見ることが出来ます。しかし cat ではファイルの中身を一気に表示するので、内容が1画面に収まらない場合、かなりの動態視力を要求されます。その点、 more, less なら 1 画面分ずつ表示してくれますからよほど修行が好きでない限りはこちらを使いたいと思うはずです。 less でファイルを表示させているときは、
"space"を押すと1画面スクロールします。
"b"を押すと1画面前に戻ります。
"q"を押すと表示を終了します。
また vi が使える人は view コマンドも便利でしょう。

目次へ
2.
ファイルを編集したい
ファイルを編集するには、テキストエディタと呼ばれるツールを使います。 UNIX でよく使われるのは、Emacs (Mule, Nemacs, Xemacs)と vi (vim, nvi) だと思います。 vi は初めての人には難しいと思います (NetHack や robots をやり込んだ人なら大丈夫ですが)。 vi も NetHack も知らない、という人は Emacs を使うのがよいでしょう。

例えば "test" というファイルを編集したいときは次のように入力します。

emacs test

もし "test" というファイルがないときは新しく作ってくれます。 Emacs の簡単な使い方については 「Emacs に対する操作」を参照してください。

目次へ
3.
ファイルの名前を変更したい
ファイルの名前を変えるには、 mv コマンドを使います。例えば "old" という名前のファイルを "new" という名前に変えるには次のように入力して下さい。

mv old new

気を付けなければいけないのは、"new" というファイルがすでに存在する場合、上書きされてしまうということです。これを防ぐためには次のように "-i" オプションを付けます。

mv -i old new

"-i" は mv コマンドに与えるオプションで、もし "new" というファイルがある場合に上書きをする前に確認を求めてきます。ここで "y" と答えると(y を押してリターンキーを押すと)上書きされます。それ以外の入力に対しては上書きをしません(ファイル名も変わりません)。また、mv コマンドの種類によっては次のような方法で上書きを防ぐことが出来ます(GNU の fileutils に含まれている mv など。 mv --version で確認できます)。

mv -b old new

このように "-b" オプションをつけると、"new" というファイルがすでに存在していたとき、元々の "new" の内容を "new~" という風に元の名前に "~" を付けた名前で保存してくれます。もしすでに "new~" というファイルもすでに存在した場合はさすがに "new~" はもとの "new" の内容で上書きされてしまいます。さらにこのふたつのオプションを同時に付けることも出来ます。

mv -bi old new

この場合、もし "new" があると、上書きしてよいか確認し、上書きした場合さらにバックアップも取ってくれます。

目次へ
4.
ファイルを移動させたい
ファイルを移動するにも、mv コマンドを使います。例えば、 "file" というファイルを "dir" というディレクトリに移動するにはつぎのように入力します。

mv file dir

こうすると、"dir" というディレクトリの中に "file" が移動します。もし "dir" の中にすでに "file" というファイルが存在すると それは上書きされてしまいます。 これを防ぐ方法は、「ファイルの名前を変更したい」 の項目で説明していますので参考にしてください。

目次へ
5.
ファイルをコピーしたい
ファイルをコピーするには cp コマンドを使います。例えば "orig" という名前のファイルを "copy" という名前にコピーするには次のように入力します。

cp orig copy

気を付けなければいけないのは、"copy" というファイルがすでに存在する場合、 上書きされてしまうということです。これを防ぐためには次のように入力します。

cp -i orig copy

"-i" は cp コマンドに与えるオプションで、もし "copy" というファイルがある場合に上書きしてもよいか確認します。ここで、"y" と答えると上書きされます。

cp コマンドも mv と同様に上書きするときにバックアップを取ることが出来ます (ファイルの名前を変更したいも参照してください)。

cp -b orig copy

こうすればもし "copy" がすでに存在したときその内容を "copy~" というファイル名でバックアップを取ってくれます。

目次へ
6.
ファイルを消したい
ファイルを消すには rm コマンドを使います。例えば "dust" というファイルを消すには次のように入力します。

rm dust

ファイルを消すという操作は取り返しがつかないので気を付けて下さい。 通常 rm は黙ってファイルを消してしまいます。しかし次のようにすれば、消す前に確認することが出来ます。

rm -i dust

"dust" を消してもよいか聞いて来ます。ここで "y" と答えれば ("y" を入力してリターンキーを押せば)ファイルは消去されます。 "y" 以外を入力するとファイルの消去は行われません。このオプションはかなり重宝します。エイリアスなどで常にこのオプションを使うようにしておくと便利かもしれません。

目次へ
7.
ファイルを圧縮したい
ハードディスクの容量が足りなくなったら、あまり使わないファイルを圧縮しましょう。ファイルを圧縮するのに使う主なコマンドには以下のようなものがあります。
* compress
* gzip
* bzip2
ほかにも pack や Windows ユーザにはおなじみの lha などもありますが、ここではわりと一般的な(と思う) gzip について説明します。 gzip はほとんどの場合 compress より圧縮効率が高いです。ちなみに bzip2 は gzip よりもさらに圧縮率が高いことが多いです。
さて "large" というファイルを圧縮する場合は次のようにします。

gzip large

もし圧縮した結果が元のファイルより小さい場合 (たまに小さくならない場合があります) "large" は "large.gz" というファイルに置き換えられます。どれぐらい圧縮できたかを表示させることも出来ます。

gzip -v large

"-v" オプションをつけると、何パーセント圧縮できたかを表示します。つまりこのとき表示された数字が大きい程圧縮されたファイルは小さくなります。では圧縮されたファイル "large.gz" を元に戻すにはどうするかというと、

gzip -d large.gz
gunzip large.gz

のどちらかを入力します。このとき拡張子「.gz」は省略することも出来ます。また、圧縮したファイルを伸長することなく中身を確認するには、

gzip -cd large.gz

と、"-c" オプションを "-d" にさらに付け加えます。

圧縮されているファイルには拡張子がついています(UNIX では拡張子は必須ではないですが)。拡張子はファイルの圧縮形式により異なります。以下に主なものを挙げます。
圧縮ソフト 拡張子
gzip .gz
compress .Z
bzip2 .bz2
pack .z
lha .lzh
UNIXでよくみるのは最初の2つではないでしょうか。

目次へ
8.
ファイルを探したい
ファイルがどこにあるか分からなくなったとき、 ls コマンドで片っ端からディレクトリをのぞいてみる、というのはひとつの手です(ぼくはむかしはそうしてました)。しかしディレクトリがたくさんあったり、その上階層が深かったりすると ls では大変です。こういうときは find コマンドを使うと便利です。

"lost" というファイルを探したいとき

find $HOME -name lost -print

"a" から始まるファイルを探したいとき

find $HOME -name a\* -print

"z" で終るファイルを探したいとき

find $HOME -name \*z -print

"a"ではじまり、"z" で終るファイルを探したいとき

find $HOME -name a\*z -print

"*" の前に "\" をつけているのは shell が "*" を展開するのを防ぐためです。これらはすべて自分のホームディレクトリの下をすべて探します。その指定をしているのは find の最初の引数 "$HOME" の部分です。ひとつめの引数にはディレクトリを指定します。ですから次のように書けば全てのディレクトリの中を検索します。

find / -name lost -print

何もそこまでしなくてよく、いまいるディレクトリの下だけを探して欲しいときは、"$HOME" のかわりに "." (ピリオド)を使います。つまり、

find . -name lost -print

というふうにします。
find はあちこちのディレクトリを見てまわるので、時間がかかります。なるべく下の階層で使うようにしたほうが早く見つけることが出来ます。

目次へ
9.
ファイルの大きさを知りたい
ファイルの大きさを計るには wc コマンドが便利です。

wc file

というように使います。こうすると "file" の行数、単語数、バイト数を出力してくれます。また複数のファイル名を列挙して wc に与えると、各ファイルの行数だけでなくそれらの合計も出してくれます。

目次へ
10.
ファイルの中から文字を探したい
ファイルのなかの特定の文字を探す方法にはいくつかあります。ある文字を含む行を抜き出すには grep コマンドを使います。 "file" というファイルから "word" を含む行だけを表示させるには

grep word file

と入力します。また、"word" が含まれている行の行番号も合わせて表示させることも出来ます。

grep -n word file

また、more や less を使ってファイルを表示させているときに文字を検索することが出来ます。表示中に "/" (スラッシュ)を入力します。すると画面の一番下段に "/" が表示されるのでそれに続けて探したい文字、もしくは単語を入力します。そしてリターンキーを押すと、その文字のあるところを表示してくれます。 "n" を押すと次を検索します。
おまけとして、現在いるディレクトリ以下のすべてのファイルの中から特定の文字列を探す、という方法も示しておきます。

find . -type f -exec grep word \{\} /dev/null \;

上記のコマンドには、ファイルがテキストであろうがデータであろうが grep を掛けてしまう、という欠点があります。しかし、それさえ目をつぶってしまえばそこそこ使えると思います。おまけなので、このコマンドの並びの詳しい解説は省略します。「ファイルを探したい」や「ディレクトリに対する操作 : ディレクトリに含まれる複数のファイルに対して同一コマンドを実行したい」を参考にして下さい。

目次へ
11.
ファイルの中の文字列を置換したい
ファイルの中の特定の文字列を変換する方法はいろいろあります。
emacs で置換を行なう場合には「emacsに対する操作: 文字列を置換したい」を参照して下さい。
ここでは sed というコマンドを使って置換する方法を説明します。
sed を用いて文字列の置換を行なう場合の基本的な書式は以下のようになります。

sed -e 's/置換したい文字列/置換後の文字列/' file

実際には sed は入力ファイルを変更せず、入力ファイルを置換された結果を画面に表示します。置換された結果をファイルに保存するためにはリダイレクションを用います (詳しくは「コマンドの結果をファイルにセーブしたい」を参照)。

sed -e 's/置換したい文字列/置換後の文字列/' file1 > file2

こうすると置換された結果が "file2" に保存されます。ここで、置換後のファイル "file2" には "file1" とは違う名前を選ぶようにして下さい。さもないと "file1" は消えてしまいます。
いくつか置換の例を示すことにしましょう。次のような内容のファイル "test.txt" があったとします。

abcdef
aabcde
abcabc

ここで、"abc" を ABC に置換してみます。

sed -e 's/abc/ABC/' test.txt

上記のコマンドを実行すると画面に次のように表示されます。

ABCdef
aABCde
ABCabc

一行目、二行目はいいのですが、三行目でははじめの "abc" しか置換されていません。完全に置き換えるには次のように "g" をつけます。

sed -e 's/abc/ABC/g' test.txt

こうすると以下のようにすべて置換されます。

ABCdef
aABCde
ABCABC

置き換えた結果をファイルに保存します。

sed -e 's/abc/ABC/g' test.txt > test2.txt

"test2.txt" で "test.txt" を置き換えるには mv コマンドを使います。

mv test2.txt test.txt

mv コマンドについては「ファイルの名前を変更したい」を参考にして下さい。
次に、行の先頭にある "abc" だけ変更してみましょう。それには以下のように置換したい文字列の先頭に "^"(サーカムフレックス) をつけます。

sed -e 's/^abc/ABC/' test.txt

結果は次のようになります。

ABCdef
aabcde
ABCabc

また、逆に行の最後にある "abc" だけを置換するには置換したい文字列の最後に "$" をつけます。

sed -e 's/abc$/ABC/' test.txt

もう少し詳しく説明すると sed は置換させたい文字列の部分に正規表現をとります。 "^" や "$" は正規表現のルールのひとつです。正規表現では上記の例以外にもさまざまな表現が可能ですが、とても複雑なのでここでは説明しません。より詳しいことは

man regex
man grep

などのオンラインマニュアルを見るか、書籍などを見て下さい。

目次へ
12.
ふたつのファイルの中身を比較したい
中身がほとんど一緒のファイルのどこが違うのかを more などでいちいち探すのは結構大変です。こんなときは diff コマンドが便利です。

diff file1 file2

と入力すると、ふたつのファイルの違うところをズラズラと表示してくれます。ただ diff の出力はちょっと分かりづらいかも知れません。例えば

,3c2,3< version 1.0< Sat Mar 21 16:10:55 1998

  • -

> version 1.2
> Sat Mar 21 19:22:41 1998

という表示が出たとします。この表示の1行目は "file1" の2,3行目と "file2" の2,3行目とが異なっていることを表しています。そして < 以下は "file1" の実際の行を示しています。 > 以下は "file2" の実際の行です。もしファイルがまったく同じである場合、diff は何も出力しません。
また、次のように "-u" オプションをつけると変更のあった部分の前後も表示することが出来ます。

diff -u file1 file2

結果は以下のようになります。

      • file1 Sun Nov 5 09:14:40 2000
      1. file2 Sun Nov 5 09:15:17 2000

@@ -3,7 +3,7 @@
/dev/hda7 /usr reiserfs defaults 1 0
/dev/hda8 /usr/local reiserfs defaults 1 0
/dev/hda9 /home reiserfs defaults 1 0

  • /dev/sda /mnt/cdrom iso9660 noauto,users,noexec 0 0
  1. /dev/hdb /cdrom iso9660 noauto,users 0 0

none /proc proc defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
/dev/hda1 /mnt/vfat vfat noauto,user 0 0

file1 と file2 で異なっている行が "-", "+" で表されます。 "-" ではじまっている行が file1 にあり、file2 にはない行です。 "+" ではじまっている行はその逆です。
また、変更点の前後 3 行が表示されます。

目次へ
13.
ふたつのファイルをひとつにくっつけたい
ふたつのファイルをひとつにくっつけたい、と思うことはあまりないかも知れません。しかしその方法は覚えておいて損はないのではないでしょうか (といってもあまり他のことに応用がきくとは思いませんが)。くっつけるには 「ファイルの中身を表示したい」 で説明した cat コマンドを使います。"file1" に "file2" の内容をくっつけて「file3」を作るときは以下のように入力します。

cat file1 file2 > file3

また "file1" の後ろに "file2" を追加するときは

cat file2 >> file1

とします。ここで気をつけなくてはならないのは、 ">>" です。まちがっても ">" を使ってはいけません。さもないと "file1" が "file2" の内容で上書きされてしまいます。

目次へ
14.
ファイルの改行コードを変換したい
改行コードとは文字どおり改行を表すコードのことです。厄介なことに、一体どのコード(数値)を改行に割り当てるか、というのが Mac, UNIX, Windows 間で異なります。 Mac では CR (carriage return) を改行コードに使います。UNIX では LF (linefeed) を使います。そして Windows では CR LF を使います(つまり二文字で改行を表す)。表にまとめると以下のようになります。
OS 文字 数値(16進数) 数値(10進数) C 言語での表記
Mac CR 0x0d 13 \r
UNIX LF 0x0a 10 \n
Windows CR LF 0x0d, 0x0a 13, 10 \r\n
ここでは UNIX 上で perl を使って改行コードを変更する方法を紹介します。
Mac -> UNIX

perl -i -pe 's/\r/\n/g' file

Windows -> UNIX

perl -i -pe 's/\r\n/\n/g' file

ここで指定した file は内容が変更されます。オリジナルを変更したくない場合は "-i" オプションを外してください。すると変換結果は標準出力に出ますので、リダイレクションで好きなファイルに保存できます (リダイレクションについては「コマンドの結果をファイルにセーブしたい」を参照して下さい)。
また nkf コマンドが利用可能であれば nkf を用いて改行コードを変更することができます。

nkf -d file > file2

ただし nkf は本来日本語ファイルの漢字コードを変換するフィルタであるため、日本語ファイルに対して上記の操作を行うと改行コードだけでなく漢字コードも変更されてしまう可能性があります。 nkf はデフォルトでは JIS コードを出力しますので、もし入力ファイル(改行コードを変えたいファイル)が JIS 以外の場合は注意して下さい。例えばもとのファイルが Shift JIS の時に漢字コードはそのままで改行コードだけを変えるには次のようにします。

nkf -d -s file > file2

"-s" オプションで主力する漢字コードに Shift JIS を指定しています。 EUC の場合は代わりに "-e" を使って下さい。
perlnkf もない場合などには sed を使って改行コードを変更することもできます。ただし '\r' や '\n' といった表現が使えないため、ちょっと大変です。コマンドライン上での Mac から UNIX への改行コード変換は以下のようになります。

sed -e 's/^M/\
/g' file > file2

^M は Ctrl-V Ctrl-M と入力します。一行めの `\' の直後には改行を入れます。そして file 中の CR を LF へと変換したものを file2 に保存します。

目次へ
15.
圧縮されたファイルの中身を展開せずに知りたい
ここでは gzip, bzip2 で圧縮されたファイルを展開せずに、その中身を確認する方法を説明します。展開せず、と言っても実際にはメモリ中には展開されます。しかし、ファイル自身は圧縮されたままです。
圧縮前のファイルがテキストファイルのような読めるファイルである場合、以下のようにして読むことができます。

gzip -cd file.gz | more

"-cd" というオプションを付けることで圧縮されたファイルの中身を画面 (標準出力)へ書き出すことができます。そのままだと、高速スクロールして読み取れないないのでパイプ("|")を使って more に出力を渡して一画面ずつ表示しています。
ファイルが bzip2 で圧縮されている場合 (file.bz2)、gzip を bzip2 に置き換えて下さい。また、古い more だとスクロールバックできないのでかわりに less を使うのも良いでしょう。

bzip2 -cd file.bz2 | less

また、上記の方法を応用して、ファイルの中身を検索することもできます。

gzip -cd file.gz | grep '^A.*Z$'

上記の例ではファイルの中身を grep へ渡して、行頭が "A" ではじまり、行末が "Z" で終わる行を抜き出しています。
リダイレクションを使って、圧縮されたファイルは残したまま、展開されたファイルを手に入れることもできます。これが便利なのは、圧縮ファイルに対して読み込みの権限は持っているものの、そのファイルがあるディレクトリに対してファイルを作る権限がない場合です (例えば /var/log に置かれた圧縮ログファイルなど)。

gzip -cd /var/log/xferlog.1.gz > $HOME/xferlog.1

目次へ

[目次(I)] [ファイル] [ディレクトリ(D)] [Shell(S)] [ジョブ(J)] [Emacs(E)] [ネットワーク(N)] [その他(O)] [トラブル(T)] [MacUNIX(M)] [UNIX 管理(A)] [番外編(X)]

www.k-tanaka.net/unix/find.html

Linuxコマンド集 [ Linuxコマンド集のTopへ ]
[ 日経LinuxのTopへ ]

uniq ソート済みのファイルから重複した行を削除する (1)

   構文  
uniq [-cdu] [-f skip-fields] [-s skip-chars] [-w check-chars] [-#skip-fields] [+#skip-chars] [--count] [--repeated] [--unique] [--skip-fields=skip-fields] [--skip-chars=skip-chars] [--check-chars=check-chars] [infile] [outfile]

   オプション  
-u, --unique ユニークな行を表示する
-d, --repeated 重複行を表示する
-c, --count 行表示の際,それぞれの行の数も表示する
-number, -f, --skip-fields=number 判断を開始するフィールドを指定する。指定したフィールド以降が判断に使用される
+number, -s, --skip-chars=number 判断を開始する文字数を指定する。指定した文字以降が判断に使用される
-w, --check-chars=number 判断の終了文字数を指定する。指定しない場合は行末とする
infile 元ファイルを指定する
outfile 結果を書き出すファイルを指定する。指定しない場合は標準出力に出力する

   説明  
ファイルで重複している行を削除する。ただし,ファイルはソートしてある必要がある

   使用例  

$ cat test.txt ← 元ファイル
Fukuda 37 14 11
Fukuda 37 14 11
Sueyasu 24 14 11
Yamada 23 55 21
Yamada 65 32 11

$ uniq ← 同じ行を削除する
Fukuda 37 14 11
Sueyasu 24 14 11
Yamada 23 55 21
Yamada 65 32 11

$ uniq -f2 -w3 test.txt ← 2フィールドから3文字目までが同じ行を削除する
Fukuda 37 14 11
Yamada 23 55 21
Yamada 65 32 11

   関連事項