• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ファイルの差分検出シェル教えてください(bsh))

ファイルの差分検出シェル教えてください

このQ&Aのポイント
  • ファイル1とファイル2で値が一致しない行番号を得る方法を教えてください。
  • 2つのファイルの行数は同じです。
  • 環境はHP-UXでbshです。awkは基本的なことしか知りません。詳しい方よろしくお願いいたします。

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

  • ベストアンサー
回答No.1

入力として想定するデータの条件がややあいまいです。 1行しか変化がない、あるいは削除や挿入があるかのような相違はないというのであれば、例示されたsdiffを使った方法でも大丈夫でしょう。しかし、 101 102 103 104 105 106 101 105 102 103 104 106 という入力の場合に得たいのは 2 3 4 5 でしょうか? この場合、diff系のツールでは、105 という行の削除や挿入があったと想定してしまうため、一致しない行 2~5 を列挙させるのは簡単ではありません。 効率を考えなければ、headとtailで抜き出しては比較するというのを繰り返す処理をshでも書けますが、入力が10行以下ならともかく、システムに負担がかかるのでやめた方がいいでしょう。 入力が比較的単純で、行内に空白を含まないとか、:などの記号を含まないとかの条件があるなら、pasteコマンドで行ごとに連結して、awkで比較すればいいと思います。 paste f1 f2 | awk '$1!=$2 {print NR}' paste -d : f1 f2 | awk -F: '$1!=$2 {print NR}' それより複雑ならば、perlがインストールされているならperlで、そうでなければCで書くのがいいと思います。エラー処理はしていませんが、下のコードは一応動くと思います。 #!/usr/local/bin/perl open F1, $ARGV[0]; open F2, $ARGV[1]; for ($lineno = 1; ($l1 = <F1>) && ($l2 = <F2>); $lineno++) { if ($l1 ne $l2) { print "$lineno\n"; } } #include <stdio.h> int main(int argc, char *argv[]) { int lineno; char buf1[1024], buf2[1024]; FILE *f1, *f2; f1 = fopen(argv[1], "r"); f2 = fopen(argv[2], "r"); for (lineno = 1; fgets(buf1, 1024, f1) && fgets(buf2, 1024, f2); lineno++) if (strcmp(buf1, buf2)) printf("%d\n", lineno); return 0; }

lts107
質問者

お礼

paste f1 f2 | awk '$1!=$2 {print NR}' で成功しました。 ご丁寧にありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • psの結果のTIME(hh:mm:ss形式)を秒数表示に変換したい

    HP-UXのbshでスクリプトを書いています。 psコマンドの結果のTIME(hh:mm:ss)をperl関数等で秒数表示に変換する方法か、 psのオプションでTIMEを秒数で表示させる方法を教えて下さい。 time=$(ps | awk '{print $3}') hour=$(echo $time | awk F=":"'{print $1}') minute=$(echo $time | awk F=":"'{print $2}') second=$(echo $time | awk F=":"'{print $3}') second=`expr hour * 3600 + minute * 60 + second` とやるのは面倒なんで1行でやりたいのです。

  • awkで列指定をして削除

    awkかsedを利用して以下のファイルを処理したいです。 1 2 3 4 5 2 1 3 4 5 1 2 3 4 5 3 1 3 4 5 一列目の値が1の行のみ削除したいです。 2 1 3 4 5 3 1 3 4 5 こんな感じです。 実際に処理するファイルは膨大な行数ががあるためprintでは難しいです。 よろしくお願いします。

  • [awk]2つのファイルを参照して1つのファイルに出力する方法

    最近プログラミング(シェル、awk)を始めた者です。 かなり大まかなものは作れるようになったのですが、急遽、大規模なデータ整理を行わないといけなくなってしまったため、皆さんの知恵を貸していただきたく質問いたしましたm(_ _)m 以下に示すような2つのファイルがあります。 (file1)         (file2) 1 6           1  1  2  10 11 2 3           2  3  5  7  8 3 5           3  6  2  12 13 4 1           4  9  4  5  19 5 2           5  10 19 1  5 6 4           6  4  8  2  9 file1を上から1行ずつ順に読んでいき、2列目の値と同じものをfile2の1列目から探します。合致したところで、file2の合致した行の2列目以降を行番号を付けて表示するというものです。 (「file1の2列目の値=file2の1列目の値」を探し、file2の合致行の値を出力。) 上記ファイルですと、結果的に 1  4  8  2  9 2  6  2  12 13 3  10 19 1  5 4  1  2  10 11 5  3  5  7  8 6  9  4  5  19 という具合になります。 2つのファイルの行数は同じではなく、また、両ファイルとも1列目が行番号というだけで、他の列の値に規則性はありません。 file2の行数は100万以上の大規模なものになります。 自分が作ったものを掲載できればよかったのですが、あいにく会社のPC内にありまして、持ち出しできないため、掲載できません。 動作環境はLinux(RedHat)になります。 他のプログラミング言語についてはまだ分からないため、awkもしくはシェルでお願いいたします。

  • awk '{print $1}' file をもっと簡単に書きたい

    awkで最も頻繁に使うのが、fileのN列目だけを抜き取ってくるという使い方なんですが ↓ awk '{print $N}' file Nとfileという2つの引数しか使わないのでこれを   my_awk N file  といった具合に間単に使える my_awk シェルを作りたいんですが、$のあたりがうまくかけません、どう直せばいいでしょうか?↓ #!/bin/csh awk '{print $$1}' $2

  • ファイル一覧を表示

    ファイル一覧を表示するため、別の質問にてシェルスクリプトを教えて いただきました。それを参考に、perlプログラムの中に入れたのですが、 期待した結果が得られません。 (シェルスクリプトで実行すると正常に動作しています) ちょうど「awk -F- '{print $2}'」の部分が実行されないのですが、 perlの中で、awkが実行できないなどの制限があるのでしょうか? それとも、書き方に問題があるのでしょうか? #! /usr/bin/perl chdir("/home/vpopmail/domains/defaultdomain"); open(DIR_IN, "ls .qmail-* | awk -F- '{print $2}' | grep -v majordomo | grep -v owner | grep -v default | sort | uniq 2> /dev/null |"); while($file=<DIR_IN>) { print $file; }

    • ベストアンサー
    • Perl
  • [Kシェル] ファイル読み込み

    最近Kシェルを始めたばかりでつまづいています。 あるログファイルの行を取得して、 その行のn番目の値を合算したいです。 例:ログファイルの中身 1,1000,AAAA,10000, 2,1000,EEEE,1000, 3,1005,CCCC,1050, ※上記で4番目を合算する場合、  12050と出力したいです。 以前Cシェルを使用していたので、 foreachのような動きを考えていたのですが、 参考書を見ると効率的でない(readを使う) という記載がされています。 ログが数万行に達する可能性があるので、 効率的なやりかたを模索していますが、 何かよい方法がありますでしょうか。 よろしくお願いいたします。

  • awkについて

    awkの勉強を始めました。入力ファイルから特定の行を抜き出し、平均値を求めようとしています。しかし、FNRとはファイルの全行のようで、FNRで割ると正しい値になりません。特定の文字($8="abc")の行だけ抜き出しているので行数は全体より小さいのですが、抜き出した行数で割るにはどうすればよいのでしょうか。

  • ファイルの中身の操作について

    今あるファイルの中身の読み込みに、 set EDPTODAY = `awk -F , '/$EDPCLND/ {print $5,$9}'` echo $EDPTODAY と書くと、構文エラーが出てしまいます。 ","区切りなので、"awk -F , "と表記したのですが・・・ ($EDPCLNDで宣言しているファイルの存在は確認しました。) お解りの方、どうお宜しくお願いいたします。

  • 【シェル】whileコマンドについて

    【シェル】whileコマンドについて OS:Solaris10 SH:Bシェル お世話になります。 whileコマンドにてテキストから、先頭に"#"(シャープ)が付いている行と、 空白行以外を読み込ませたいです。 ところが、メイン処理にawkコマンドを入れると、テキストを読む時点で、 行全体ではなく、指定したフィールド内の文字列を読みにいくため、 "#"(シャープ)が付いている行を無視することができません。 ====== while.sh ====== #!/bin/sh while read LINE do echo $LINE | awk '{print $2}' done < list.txt | grep -v "^#" | grep -v "^$" ====================== ------ list.txt ------ 1 2 3 #4 5 6 7 8 9 ---------------------- ****** 出力結果 ****** 2 5 8 ********************** ** 出力させたい結果 ** 2 8 ********************** whileコマンドのオプション等で、テキスト内に特定の記号がある行は 無視して読み込ませる方法がありましたら、ご教授ください。 宜しくお願い致します。

  • ある単語を含む行と、1つ前の行とを削除するシェル

    UNIX初心者です。 シェル(Korn)で、あるファイル中に、単語 "iwa"を含んだら、その行と、1つ前の行とを削除したいシェルを作りたいのです。  つまり、grep, sed, awk などで、"iwa"を含む行がみつかったら、その行(iwaを含む行)と、なおかつ、1行前の合わせて、2行を削除するシェルを作りたいのですが、行番号(NR?)などを使うのでしょうか? よろしく、お願いします。

X91FがWindows11にバージョンアップ
このQ&Aのポイント
  • Windows10から11にはバージョンアップできませんか?要件は満たしているようですが?
  • LenovoのタブレットX91FをWindows11にアップグレードできるか疑問です。
  • X91FはWindows10からWindows11にアップデート可能なのか、要件を満たしているのにアプデできない状況です。
回答を見る