概要

HDFSをコマンドラインから操作する際に使える引数の一覧です。

下記のページを参考にしています。

HDFS File System Shell Guide
http://hadoop.apache.org/common/docs/r0.20.0/hdfs_shell.html

@Date 2011/11/12
@Versions Hadoop0.20, Ubuntu10.04, CDH3

ls / lsr

lsはLinuxなどのlsコマンドと同じ、指定ディレクトリのファイルの一覧を表示する。

$ hadoop fs -ls /user/hdfs
Found 1 items
drwxr-xr-x   - hdfs supergroup          0 2011-11-11 01:35 /user/hdfs/sample

ディレクトリを指定しない場合は/user/${ユーザ名}を見に行く。

ディレクトリが存在しない場合は、以下のようなエラーになる。

$ hadoop fs -ls
ls: Cannot access .: No such file or directory.

hadoop fs -ls が上記のエラーになる場合は、/user/${ユーザ名}をmkdirで作ってあげる。

lsrは再帰的に指定ディレクトリ配下のファイルを見に行って一覧表示してくれる。

$ sudo -u hdfs hadoop fs -lsr /user/hdfs
drwxr-xr-x   - hdfs supergroup          0 2011-11-11 01:35 /user/hdfs/sample
-rw-r--r--   1 hdfs supergroup  500000000 2011-11-10 23:28 /user/hdfs/sample/part-00000
-rw-r--r--   1 hdfs supergroup  500000000 2011-11-10 23:28 /user/hdfs/sample/part-00001

-lsr / とかやると全ファイルがだーっと出力されることになる。

touchz / mkdir

touchzは空ファイルを生成します。

// foo.txtというファイルを作る
$ hadoop fs -touchz foo.txt

// 0バイトのファイルができている
$ sudo -uhdfs hadoop fs -ls
Found 1 items
-rw-r--r--   1 hdfs supergroup          0 2011-11-12 15:17 /user/hdfs/foo.txt

普通のtouchコマンドだと更新日時を変更する用途で使うけど、そういう機能はないらしい。0バイトじゃないファイルにtouchすると以下のようなエラーが出る。

// 0バイトじゃないbar.txtというファイルに対してtouchzを実行
$ sudo -uhdfs hadoop fs -touchz bar.txt
touchz: bar.txt must be a zero-length file

mkdirはディレクトリを生成する。

$ hadoop fs -mkdir dir

$ hadoop fs -ls
Found 1 items
drwxr-xr-x   - hdfs supergroup          0 2011-11-12 16:09 /user/hdfs/dir

touchzやmkdirは引数に複数のパスを指定してまとめて作成することもできる。

// dir1とdir2をまとめて作成
$ hadoop fs -mkdir dir1 dir2

$ hadoop fs -ls
Found 2 items
drwxr-xr-x   - hdfs supergroup          0 2011-11-12 19:18 /user/hdfs/dir1
drwxr-xr-x   - hdfs supergroup          0 2011-11-12 19:18 /user/hdfs/dir2

cp / mv

cpは名前の通りファイルのコピーをします。ディレクトリもコピー普通にできる。

// bar.txtというファイルをbaz.txtという名前でコピー
$ hadoop fs -cp bar.txt baz.txt

$ hadoop fs -ls
Found 2 items
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 15:40 /user/hdfs/bar.txt
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 16:21 /user/hdfs/baz.txt

mvはファイルを移動する。移動先に同名のファイルがある場合はエラーになる。

// bar.txtというファイルをfoo.txtという名前でmv
$ hadoop fs -mv bar.txt foo.txt

$ hadoop fs -ls
Found 2 items
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 16:21 /user/hdfs/baz.txt
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 15:40 /user/hdfs/foo.txt

// 同名のファイルがある場合はエラー
$ hadoop fs -mv foo.txt baz.txt
mv: Failed to rename hdfs://tora:54310/user/hdfs/foo.txt to baz.txt

cp、mvはコピー元(移動元)ファイルを複数指定できる。

// foo.txtとbar.txtというファイルとdirというディレクトリがあったとする
$ hadoop fs -ls
Found 3 items
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 19:00 /user/hdfs/bar.txt
drwxr-xr-x   - hdfs supergroup          0 2011-11-12 18:59 /user/hdfs/dir
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 18:48 /user/hdfs/foo.txt

// foo.txtとbar.txtをdirにコピー
$ hadoop fs -cp foo.txt bar.txt dir

// dirの中に両方のファイルがコピーされてる
$ hadoop fs -ls dir
Found 2 items
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 19:03 /user/hdfs/dir/bar.txt
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 19:03 /user/hdfs/dir/foo.txt

あとアスタリスクとか正規表現も人並みに使える。

// アスタリスクを使った指定とか
$ hadoop fs -cp *.txt dir

// [a-z]のような表現も可能
$ hadoop fs -cp file[1-2].txt dir

rm / rmr / expunge

rmはファイルを削除する。ディレクトリは削除できない。

// ファイルの削除
$ hadoop fs -rm foo.txt
Deleted hdfs://tora:54310/user/hdfs/foo.txt

// ディレクトリを削除しようとするとエラーになる
$ hadoop fs -rm dir
rm: Cannot remove directory "hdfs://tora:54310/user/hdfs/dir", use -rmr instead

rmrrm -rfのようにファイルでもディレクトリでも削除する。

$ hadoop fs -rmr dir
Deleted hdfs://tora:54310/user/hdfs/dir

expungeはTrashを空にする。HDFSは削除命令を受けた場合に、まずはデータをtrashディレクトリに移動して一定期間経つと削除を実行するらしい。

$ hadoop fs -expunge

get / getmerge / copyToLocal / moveToLocal

getはHDFS上のファイルをローカルにコピーする。

// HDFS上のfoo.txtというファイルをローカルにbar.txtという名前でコピー
$ hadoop fs -get foo.txt bar.txt

// 既にファイルがあると怒られる(copyToLocalも同じ挙動)
$ hadoop fs -get foo.txt bar.txt
get: Target bar.txt already exists

getmergeはディレクトリを引数に指定して、その中のファイルを連結した結果をローカルにコピーする。

// dirというディレクトリの中に入ってる中身をマージして、merge.txtというファイルに出力
$ hadoop fs -getmerge dir merge.txt

// ディレクトリの中のファイルが改行区切りでマージされている
$ cat merge.txt
foo
bar
baz

copyToLocalはgetと同じく、HDFSからファイルを取得してローカルに出力する。copyToLocalは出力先がローカル限定という点で少し違うらしい。

$ hadoop fs -copyToLocal foo.txt bar.txt

mvToLocalといういかにもローカルにファイルを移動してくれそうなコマンドも用意されているのだけど、これはまだ未実装のようで実行しても「Not implemented yet」と表示される。

put / copyFromLocal / moveFromLocal

putはローカルにあるファイルをHDFS上に配置します。

// ローカルのfoo.txtというファイルをHDFS上に持っていく
$ hadoop fs -put foo.txt foo.txt

$ hadoop fs -ls
Found 1 items
-rw-r--r--   1 hdfs supergroup          4 2011-11-12 23:19 /user/hdfs/foo.txt

// 既にファイルがある場合はエラー(copyFromLocalも同じ挙動)
$ hadoop fs -put foo.txt foo.txt
put: Target foo.txt already exists

// 標準出力のをHDFS上のファイルに出力したりもできる
$ echo "I have a dream" | hadoop fs -put - bar.txt

copyFromLocalも、元ファイルがローカルに限定される以外は同じ動作。

$ hadoop fs -copyFromLocal foo.txt foo.txt

moveFromLocalは、HDFS上にファイルをコピーした後、ローカルにあるコピー元のファイルを削除する。

$ hadoop fs -moveFromLocal foo.txt foo.txt

あと、手元で動かしたら、HDFS上に同名のファイルがあっても上書きする挙動になっていた。

cat / tail / text

catは指定したHDFS上のファイルを標準出力する。

$ hadoop fs -cat bar.txt
I have a dream

// 別にHDFS以外でも出せはするけど
$ hadoop fs -cat file:///home/user/temp/bar.txt

headコマンドはないので上から指定行を読みたい場合はpipeを利用する。

// 上から100行読む
$ hadoop fs -cat bar.txt | head -10

tailは最後の1KBを出力する。

// 下1KBを表示
$ hadoop fs -tail bar.txt

// 一般的なtailのように下から指定行表示したい場合は、たぶんこう
$ hadoop fs -tail bar.txt | tail -100

// tail -f も使える
$ hadoop fs -tail -f bar.txt

textは普通にテキストファイルを出力することもできるけど、MapReduceの出力なんかで使われるSequenceFileも読める。

$ hadoop fs -text bar.txt

stat / test

statは指定されたパスの状態を確認できる。具体的には以下のような。

%n : 名前
%b : ファイルサイズ
%o : ブロックサイズ
%r : レプリケーション数
%y : 最終更新日時

hadoop fs -stat [format] path の形式で指定する。

$ hadoop fs -stat "%n %b %o %r %y" bar.txt
bar.txt 36 67108864 1 2011-11-12 14:42:36

testは指定パスが存在するか、ファイルか、ディレクトリかなどを判定する。

結果はreturn codeで返ってくる。0なら正解、1なら不正解。

// 存在チェックをする時は-e
$ hadoop fs -test -e bar.txt
$ echo $?
0

// 存在しないファイルをチェックすると0以外が返る
$ hadoop fs -test -e unknown.txt
$ echo $?
1

// -zは指定パスが0バイトのファイルかチェックする
$ hadoop fs -test -z zero.txt
$ echo $?
0

// -zを存在しないファイルに実行するとエラー
$ hadoop fs -test -z none.txt
test: File does not exist: none.txt

// -dはディレクトリかどうかチェック
$ hadoop fs -test -d dir
$ echo $?
0

// ファイルの場合は0以外が返る(存在しない場合はエラー)
$ hadoop fs -test -d file.txt
$ echo $?
1

chmod / chown / chgrp

HDFSのファイルはLinuxみたいに権限が付与できる。

chmodは権限を変更できる。

// 644のファイルがあったとする
$ hadoop fs -ls
Found 1 items
-rw-r--r--   2 hdfs supergroup       8759 2011-11-13 16:14 /user/hdfs/foo.txt

// chmodで777を指定してみる
$ hadoop fs -chmod 777 foo.txt
hdfs@tora:/home/masato/temp$ hadoop fs -ls
Found 1 items
-rw-rw-rw-   2 hdfs supergroup       8759 2011-11-13 16:14 /user/hdfs/foo.txt

// -Rで再帰的に設定可能
$ hadoop fs -chmod -R 777 dir

ユーザやグループなどの情報も持っており、chownchgrpで変更できます。

// オーナーをmapredユーザに変更する
$ hadoop fs -chown mapred foo.txt
$ hadoop fs -ls
Found 1 items
-rw-rw-rw-   2 mapred supergroup       8759 2011-11-13 16:14 /user/hdfs/foo.txt

// グループをmapredに変更する
$ hadoop fs -chgrp mapred foo.txt
$ hadoop fs -ls
Found 1 items
-rw-rw-rw-   2 mapred mapred           8759 2011-11-13 16:14 /user/hdfs/foo.txt

// ユーザとグループをまとめて変更する
$ hadoop fs -chown hdfs:supergroup foo.txt
$ hadoop fs -ls
Found 1 items
-rw-rw-rw-   2 hdfs supergroup       8759 2011-11-13 16:14 /user/hdfs/foo.txt

// -Rを付けると再帰的に実行される
$ hadoop fs -chown -R mapred:mapred dir

count / du / dus

countはファイル数やファイルサイズなんかを表示します。-qを付けるとQUOTAの情報とかも見れます。

// ディレクトリ数、ファイル数、サイズ、名前
$ hadoop fs -count /user/hdfs
2	3	72858	hdfs://tora:54310/user/hdfs

// -qを付けた場合(QUOTA, REMAINING_QUATA, SPACE_QUOTA, REMAINING_SPACE_QUOTA, DIR_COUNT, FILE_COUNT, CONTENT_SIZE, FILE_NAME)
$ hadoop fs -count -q /user/hdfs
none	inf	none	inf	2	3	72858	hdfs://tora:54310/user/hdfs

duは指定パスのファイルやディレクトリのサイズを表示します。

// ディレクトリについては配下のファイルサイズの合計が表示される
$ hadoop fs -du /user/hdfs
Found 2 items
64099       hdfs://tora:54310/user/hdfs/dir
8759        hdfs://tora:54310/user/hdfs/foo.txt

dusは指定パス配下の合計ファイルサイズを出します。

$ hadoop fs -dus /user/hdfs
hdfs://tora:54310/user/hdfs	72858

setrep

setrepはレプリケーションの数を指定する。

// foo.txtのレプリカを2個に設定する
$ hadoop fs -setrep 2 foo.txt

// statでレプリカの数を見るとちゃんと2になってる
$ hadoop fs -stat %r foo.txt
2

// -w 2 -R のように指定すると、ディレクトリ配下を再帰的にレプリカの設定を2にする
$ hadoop fs -setrep -w 2 -R dir