複数のファイルをdiffで比較する方法とエラーの対処法

このQ&Aのポイント
  • 複数のファイルをdiffコマンドを使用して比較するためのシェルスクリプトを作成しましたが、エラーメッセージが表示されてしまいます。
  • エラーメッセージ「diff: 「ファイル名」の後のオペランドがありません」が表示され、ファイルの比較ができません。
  • 原因は、ファイル名の指定が正しくないことであり、変数$tempの中身が誤っています。正しいファイル名を指定することで問題が解決する可能性があります。
回答を見る
  • ベストアンサー

複数のファイルをdiffで比較するために以下のシェルを作成しましたが

複数のファイルをdiffで比較するために以下のシェルを作成しましたが diff: 「ファイル名」の後のオペランドがありません とエラーが表示されてしまいます。 htmlディレクトリとhtml_bkディレクトリ内にある ファイルを比較する処理になります。 ======================================== find ./html -name *.html -type f | while read f do echo $f | sed 's/html/html_bk/g' $temp diff $f $temp >> diff.txt done ====================================== $tempの中身はhtml_bkと変更されていました。 原因が分かる方がいましたら教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

> htmlディレクトリとhtml_bkディレクトリ内にある > ファイルを比較する処理になります diff -r html html_bk で一発なんですけど.... このシェルスクリプトを完成させるなら # -nameで*を使いたいときは""で括る find ./html -name "*.html" -type f | while read f do # 実行結果を変数に取り込むならバッククオートを使う # 先頭が必ず ./html/ になるから、htmlを置き換えればいいのだけど、 # より正確にするなら、こんな感じ temp=`echo $f | sed 's|^\./html/|./html_bk/|'` # ファイル名の空白が含まれることも考慮して、""で括る diff "$f" "$temp" >> diff.txt done

momo_chi_chi
質問者

お礼

kmeeさん、返答ありがとうございます。 教えて頂いたとおりに書いたら動きました。 それに、-rオプションという便利なものがあったんですね。 丁寧に教えてもらったおかげで注意する点や勉強不足がはっきりと 分かりました。 ありがとうございました。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

いろいろ問題あるなぁ.... ・「$tempの中身はhtml_bkと変更されていました。」と書かれていますが, temp を変更している部分が見当たりません. 「更新されていた」というのはどのように確かめたのですか? ・*.html はクォートしないとまずい ・sed で置換する時になぜ g をつけている? ・そもそもこれはシェルスクリプトであってシェルではない

momo_chi_chi
質問者

補足

Tacosanさん返答ありがとうございます。 変更内容は、echo $tempで画面に出力させて確認したのですが 確認の方法が間違っていましたでしょうか? htmlのクウォーとsedのgに関しては、記述が間違っておりました。 原因が分からなかったので、いろいろ試していた際に間違った記述をコピーしてしまいました。 シェルについては、痛いご指摘です。 何せほとんど書いたことがありませんので良くわかっておりません。

関連するQ&A

  • SED スクリプトファイルを複数のファイルに作用させたい。

    SEDのスクリプトファイル(henkan.sed)を作りました。 このスクリプトを実行させたい対象ファイルが15個あります。(temp01.txt~temp15.txt) > sed -f henkan.sed temp01.txt > kekka01.txt > sed -f henkan.sed temp02.txt > kekka02.txt           ・           ・           ・ > sed -f henkan.sed temp15.txt > kekka15.txt これはあまりにもしんどいです。何かよい方法はあるでしょうか。 また、コマンドラインから一つのスクリプトファイルを複数の対象ファイルに作用させることは可能でしょうか。 よろしくお願いします。

  • ファイルから文字列を読み込むシェルスクリプトの作成

    現在シェルスクリプトの勉強をしています。 ファイルから文字列を読み込み表示するだけのシェルスクリプトを 作成しているのですが、エラーが出てうまくいきません。 ./test.sh: line 10: syntax error near unexpected token `done' 以下の通りファイルを作っています。 改行コードはLF、文字コードはSJISとなっています。 どのあたりが間違っているのか教えて頂けますでしょうか。 よろしくお願いします。 test.sh --------------------- #!/bin/sh LIST=./abc.lst while read F1 echo ${F2} break done < ${LIST} } --------------------- abc.lst --------------------- AAA BBB CCC ---------------------

  • unixのシェルでファイル内容を読み込む

    ど初心者です。わかりづらいかもしれませんが宜しくお願いします。 以下のような処理を行いたいと考えています。 (1) aaa.sh(シェルスクリプト)にてバッチプログラムを起動 (2)バッチでエラーの場合、結果ファイル(bbb.txt)に「1」を出力する。 (3)aaa.sh(シェルスクリプト)にて結果ファイルの内容を読み取り「1」の場合は、再度バッチプログラムを起動する。 このうち(3)の処理にて、結果ファイルの読み込み方法がわかりません。 調べた結果、以下のような処理で可能なようですが・・ while read LINE; do echo $line done < aaa.txt 読み込むのは1行なので、ループ処理にはしたくないのですが、例えば「read LINE aaa.txt」のような簡単なコマンドで、ファイルの中身を読み込むことはできないのでしょうか? 実はUNIXが初めてで、しかもスケジュールに余裕がないため焦っております。 なにぶん知識不足な故、ちんぷんかんぷんな質問かも知れませんが、よろしくお願いいたします。

  • シェルスクリプト ファイルパス違いによって実行結果が違う 比較

    シェルスクリプト(bシェル)を作成しています。fileA.txtの中身を一行ずつ読み込んで、fileB.txtと比較を行うプログラム(sample.sh)です。 設定しているファイルのパスの違いによって実行が出来るものと出来ないものがあり、その原因がわかりません。 【1】自分のホームディレクトリ(MyDIR)にすべてのファイルを置いている FILEA=/home/MyDIR/TEST/fileA.txt FILEB=/home/MyDIR/TEST/fileB.txt while read line do grep -v "$line" "$FILEB" done < $FILEA  このプログラムは正常に実行できます 【2】FILEA,Bを/tmpの下に作ったTESTディレクトリの下に置いている sample.shは/home/MyDIR/TESTの下、fileA,Bは/tmp/TESTの下。 set FILEA=/tmp/TEST/fileA.txt set FILEB=/tmp/TEST/fileB.txt while read line do grep -v "$line" "$FILEB" done < $FILEA  ファイルのパスをこのように変更すると、while:構文が間違っています。というエラーが出て実行できません。whileの中に入れていないようです。スペルミスはありませんし、パスが違うだけでなぜ実行が出来なくなるのでしょうか? よろしくお願いします。

  • シェル:複数ファイルの計算方法に困ってます

    ファイル毎に使用容量を管理するシェル作成中、下記の内容で困ってます。いいアイデアを教えていただけないでしょうか。 よろしくお願いします。 【 前日分 】old.txt                カウント 使用量 ファイル名                5 10 aaaaaa.txt         5 15 bbbbbb.txt 3 20 dddddd.txt  【 当日分 】 new.txt  カウント 使用量 ファイル名 1 50 aaaaaa.txt 1 65 bbbbbb.txt 1 15 cccccc.txt 【理想】new.tmp カウント 使用量 ファイル名 6 60 aaaaaa.txt 6 80 bbbbbb.txt 1 15 cccccc.txt 3 20 dddddd.txt new.txtと同じ名前がold.txtにあれば、カウント列・使用量列をそれぞれ加算しnew.tmpに出力。 new.txtにあってold.txtに無い場合はそのまま行をnew.tmpに出力 new.txtになくてold.txtにある場合もそのまま行をnew.tmpに出力 説明 カウント・・・毎日加算処理をしカウントを上げていく        (よってnew.txtのカウントは必ず "1") 使用量・・・ファイルの使用量 ファイル名・・・ファイル名 上記のようなことは出来るでしょうか? diff・grep・sedとか調べてみたんですが融合技が見当つかず・・・ よろしくお願いします。

  • [シェルスクリプト]ファイル変換後に空になる

    ubuntu ver9.04 上で以下のような連番(01~09)の付いたCSVファイルの4,5,11,12列目のフィールドを抜きだし区切り文字を","から空白に置き換え.datファイルにするというシェルプログラムを作っています. たまに一部のファイルが空で出力されます.(ファイルは出力されるのですが中身がない)なぜでしょうか? 誰かご教示願います. #!/bin/bash passB="./data/sw0174-h13-d0-" passA="0001" kaku=".csv" dat=".dat" #echo $passB # input file number echo 'Please input minimum file number (ex.03)!' read fnumin echo 'Please input maximum file number (ex.05)!' read fnumax delta=`expr $fnumax - $fnumin` echo "delta=" echo $delta cnt=0 while [ "$cnt" -le "$delta" ] do echo "cnt=" echo $cnt fpass=$passB$fnumin$passA$kaku echo $fpass cvtf=$passB$fnumin$passA$dat echo $cvtf cut -d ',' -f 4,5,11,12 $fpass > $cvtf cat $cvtf | sed -e 's/,/ /g' > $cvtf cnt=`expr $cnt + 1` fnumin=`expr $fnumin + 1` fnumin=0$fnumin echo "fnumin=" echo $fnumin done

  • シェル ファイルの中身によって特定の処理

    シェルスクリプトに関する質問です。 少しシェルで言語風なものを作ってみようと思い、作成したのですが、上手くいかないので質問させて頂きました。内容は、特定の文字がファイルに記載されているか判定して、 特定の文字だったら処理をするというものです。 現在、このようなソースになっています↓ #!/bin/sh - #ファイルを設定(仮) file_name="dummy.sh" #行数を変数へ格納 line=$(wc -l ${file_name}) #行数をlog.txtへ書き込む echo ${line} > log.txt #行数以外にファイル名があるので削除 sed -i "s/$file_name//g" log.txt #行数を格納 Line=$(cat log.txt) i=0 #全ての行を変数へ格納 #ここが問題 配列に変数が使えない!? while [ $i = ${Line} ] do array[$i]=$(sed -n "${i}p" ${file_name}) expr `${i} + 1` done # 格納した変数をチェックして、 # 指定された文字(hello)が書かれていればhelloと表示させる b=0 while [ $b = ${main_file} ] do if [ array[$b] = "hello" ] then echo "hello" fi expr `$b + 1` done ここで、配列を利用し、変数への代入が出来ませんでした。 ただ、エラーは表示されません。。。 環境はUbuntu10.10です。 何もいじっていないので、たぶん大丈夫だと思うんですが・・・ 何か解決策はありませんか? また、コレよりいい方法などがあればぜひ教えてください。

  • ファイルを行ごとに比較するシェルスクリプトについて

    ファイルを行ごとに比較するシェルスクリプトをご教授ください。 例えば(master.txt)(a.txt)(b.txt)(c.txt)(ok.txt)(ng.txt)と4つのファイルがあり、 (master.txt)と(a.txt)の行を比較し(a.txt)の中のある行が(master.txt)の行と一致した場合(ok.txt)に (master.txt)の行と一致しなかった場合(ng.txt)に入れる。 その後(master.txt)と(b.txt)の比較し(a.txt)が使用したものと同じ(ok.txt)or(ng.txt)に入れる・・・ といったように繰り返していくシェルスクリプトはどのようにして作成するのでしょうか? txtファイルの中の行はランダムに入っており、x.txtの一行一行ををmaster.txtの全行と比較する必要があります。 自分で作ってみたものは、while文を2重で使い一行ずつ取り出しcase文で行が一致した物を(ok.txt)に入れる 所までは成功しているのですが、複数回繰り返す時にどのようなロジックで不一致行を(ng.txt)に入れる ことができるのかが考え付きませんでした。 よろしくお願いいたします。

  • シェルスクリプトの実行結果が毎回異なってしまいます

    お世話になります。 UNIX初心者です。 作成したシェルスクリプトを実行するたびに、結果が異なります。 正常に実行され、期待どおりの結果になる場合もありますが、 スクリプトの修正などをを全くしていないにも関わらず、ほぼ毎回異なる 結果になります。 ※変数に値が代入されなかったりして、文法エラーになったり、 エラーにならなくても結果が毎回違います。 以下に問題のスクリプトを記載しておりますが、内容を簡単に言いますと、 csvファイルの内容(ファイルサイズ、ファイル名の一部)を 読み取り、その内容を新しいファイルに書き出すというものです。 ※もちろんスクリプト実行時に読み込むcsvファイルは毎回同じものを使用しています。 初心者なので、何が悪いのか目処すらたちません。 ご教示頂ければ幸いです。 宜しくお願い致します。 【スクリプト内容】(長くなってしまいすいません) #!/bin/sh find /var/apache/htdocs/colo/test_batch2/ -name "RACK_*" > temp_file1 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file1 |tee temp_file1 old_file_name=`cat temp_file1` sed -e s/csv/ar/ temp_file1 |tee temp_file1 file_name=`cat temp_file1` sed -e s/RACK_//g temp_file1 |tee temp_file1 sed -e s/.ar//g temp_file1 |tee temp_file1 file_cre_time=`cat temp_file1` wc -c $old_file_name |tee temp_file2 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file2 |tee temp_file2 sed -e s/$old_file_name//g temp_file2 |tee temp_file2 file_size=`cat temp_file2` echo $file_name echo $file_size echo $file_cre_time touch $file_name echo '"'$file_cre_time'"' ',"'$file_size'"'|tee $file_name echo $file_name|tee temp_file3 sed -e s/ar/txt/g temp_file3 |tee temp_file3 txt_name=`cat temp_file3` touch $txt_name find /var/apache/htdocs/colo/test_batch2/ -name "AREA_*" > temp_file4 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file4 |tee temp_file4 old_file_name=`cat temp_file4` sed -e s/csv/ar/ temp_file4 |tee temp_file4 file_name=`cat temp_file4` sed -e s/AREA_//g temp_file4 |tee temp_file4 sed -e s/.ar//g temp_file4 |tee temp_file4 file_cre_time=`cat temp_file4` wc -c $old_file_name |tee temp_file5 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file5 |tee temp_file5 sed -e s/$old_file_name//g temp_file5 |tee temp_file5 file_size=`cat temp_file5` echo $file_name echo $file_size echo $file_cre_time touch $file_name echo '"'$file_cre_time'"' ',"'$file_size'"'|tee $file_name echo $file_name|tee temp_file6 sed -e s/ar/txt/g temp_file6 |tee temp_file6 txt_name=`cat temp_file6` touch $txt_name find /var/apache/htdocs/colo/test_batch2/ -name "BUIL_*" > temp_file7 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file7 |tee temp_file7 old_file_name=`cat temp_file7` sed -e s/csv/ar/ temp_file7 |tee temp_file7 file_name=`cat temp_file7` sed -e s/BUIL_//g temp_file7 |tee temp_file7 sed -e s/.ar//g temp_file7 |tee temp_file7 file_cre_time=`cat temp_file7` wc -c $old_file_name |tee temp_file8 sed -e s/\\/var\\/apache\\/htdocs\\/colo\\/test_batch2\\///g temp_file8 |tee temp_file8 sed -e s/$old_file_name//g temp_file8 |tee temp_file8 file_size=`cat temp_file8` echo $file_name echo $file_size echo $file_cre_time touch $file_name echo '"'$file_cre_time'"' ',"'$file_size'"'|tee $file_name echo $file_name|tee temp_file9 sed -e s/ar/txt/g temp_file9 |tee temp_file9 txt_name=`cat temp_file9` touch $txt_name

  • Perlについて

    あるテキストファイルからディレクトリだけを抜き出して各ディレクトリにパーミッションをつけたいのですがやりかたはシェルスクリプトでやろうとかんがえています。 #!/usr/bin/bash while read x1 x2 x3 x4 x5 x6 x7 x8 x9 ; do echo $x1 | grep ^d > /dev/null 2>&1 if(($?==0));then echo mkdir -p $x9 fi done < file.txt とディレクトリを作るところからパーミッションはどう書けばわかりません。当方初心者なのでわからないことがおおいです。 ご教授お願いします。 ~