同名ファイルでサイズ違いのものだけを表示

estis2009/04/07 (火) 18:06 に投稿

やりたいこと:

次のような二つのディレクトリがあり、同じ名前のファイルがそれぞれあるが、その内サイズが異なるファイル名を表示する。
これをワンライナーで実現する。

$ ls -l *

TEST_1:
total 32
-rw-r--r--  1 estis  estis    4  4  7 09:44 test01
-rw-r--r--  1 estis  estis   44  4  7 09:49 test02
-rw-r--r--  1 estis  estis  118  4  7 09:46 test03
-rw-r--r--  1 estis  estis   40  4  7 09:47 test04

TEST_2:
total 32
-rw-r--r--  1 estis  estis    4  4  7 09:44 test01
-rw-r--r--  1 estis  estis    4  4  7 09:45 test02
-rw-r--r--  1 estis  estis  118  4  7 09:46 test03
-rw-r--r--  1 estis  estis   80  4  7 09:48 test04

こういう状態なので、欲しい答えは、
test02とtest04。

(1) awkを使ってみた。

$ ls -l * |awk '{if(NF > 2) print $9,$5}'| sort | awk '{if(x != $1){x = $1; y = $2}else if(y != $2) print $1}'

test02
test04

(2) perlを使ってみた。

$ ls -l *|perl  -wnla -e '$filesize{$F[8]}{$F[4]} = 1 if(@F > 2);END{ for(keys %filesize){ print $_ if(scalar keys %{$filesize{$_}} != 1)}}'

test02
test04

どちらも同じように答えるが、ここでディレクトリをもう一つ増やしてこんな感じにしてみた。

$ ls -l *

TEST_1:
total 32
-rw-r--r--  1 estis  estis    4  4  7 09:44 test01
-rw-r--r--  1 estis  estis   44  4  7 09:49 test02
-rw-r--r--  1 estis  estis  118  4  7 09:46 test03
-rw-r--r--  1 estis  estis   40  4  7 09:47 test04

TEST_2:
total 32
-rw-r--r--  1 estis  estis    4  4  7 09:44 test01
-rw-r--r--  1 estis  estis    4  4  7 09:45 test02
-rw-r--r--  1 estis  estis  118  4  7 09:46 test03
-rw-r--r--  1 estis  estis   80  4  7 09:48 test04

TEST_3:
total 32
-rw-r--r--  1 estis  estis    4  4  7 16:15 test01
-rw-r--r--  1 estis  estis   57  4  7 16:21 test02
-rw-r--r--  1 estis  estis  118  4  7 16:15 test03
-rw-r--r--  1 estis  estis   40  4  7 16:15 test04
-rw-r--r--  1 estis  estis    0  4  7 16:18 test05

test05というファイルがTEST_3ディレクトリにしか存在しない。
test02ファイルは3ファイル全てサイズが異なる。

ここで欲しい答えは、
test02とtest04とtest05、TEST_3ディレクトリ以外のtest05ファイルのサイズはundefという解釈で。

さて、さっきのコマンドを実行してみると

(1)

$ ls -l * |awk '{if(NF > 2) print $9,$5}'| sort | awk '{if(x != $1){x = $1; y = $2}else if(y != $2) print $1}'

test02
test02
test04

(2)

$ ls -l *|perl  -wnla -e '$filesize{$F[8]}{$F[4]} = 1 if(@F > 2);END{ for(keys %filesize){ print $_ if(scalar keys %{$filesize{$_}} != 1)}}'

test02
test04

という結果になり、満足できない。

(3) awkを使う方法でコマンドを修正。

$ ls -l * |awk '{if(NF > 2) filesize[$5" "$9]++}END{for(i in filesize){if (filesize[i] == 1) print i}}'|awk '{file[$2]}END{for( i in file)print i}'

test02
test04
test05

(4) perl版を一工夫してみた。

$ ls -l *|perl  -wnla -e '$filesize{$F[8]}{$F[4]}++ if @F > 2;END{ for(keys %filesize){ $file = $_; for(keys %{$filesize{$file}}){ print $file if($filesize{$file}{$_} == 1)}}}'

test02
test02
test02
test05
test04

 これだと間違いではないが冗長。なので、

(4')

$  ls -l *|perl  -wnla -e '$filesize{$F[8]}{$F[4]}++ if @F > 2;END{ for(keys %filesize){ $file = $_; for(keys %{$filesize{$file}}){ print $file if($filesize{$file}{$_} == 1)}}}'|uniq

test02
test05
test04

 uniqに頼った。

(5) いやいや、やっぱりperlだけで何とかするんだ〜!

$ ls -l *|perl  -wnla -e '$filesize{$F[8]}{$F[4]}++ if (@F > 2);END{ for(keys %filesize){ $file = $_; for(keys %{$filesize{$file}}){ $filename{$file}++ if($filesize{$file}{$_} == 1)}} print join "\n", keys %filename}'

test02
test04
test05

 できた。