CentOS7のjoinコマンドでファイルを結合する方法

このQ&Aのポイント
  • CentOS7のjoinコマンドを使用して2つのファイルを結合する方法を教えてください。
  • ファイル1にあるレコードのカラム2とカラム3の値は、ファイル2のレコードでカラム1が一致する場合に対応するカラム2とカラム3の値を引用したいです。
  • ただし、ファイル1にしかないレコードのカラム2とカラム3は固定文字"0 PASSWORD0"を表示するようにしたいです。
回答を見る
  • ベストアンサー

CentOS7のjoinコマンドの-eオプション

CentOS7のjoinコマンドで2つのファイルの中身を接続したいのですが、 <File1> ta**@yahoo.jp hana**@yahoo.jp ji**@yahoo.jp - <File2> ta**@yahoo.jp 1 password1 hana**@yahoo.jp 2 password2 の場合、「File1にあるレコードの、カラム2、カラム3の値はカラム1が一致するFile2のレコードの対応数るカラム2、カラム3の値を引用する」と言う仕様で2ファイルを結合したいと思います。 「但し、File1にしかないレコードのカラム2、カラム3は固定文字 "0 PASSWORD0"を表示する」と言う仕様で、 https://okwave.jp/qa/q6294003.html?utm_source=twitterfeed&utm_medium=twitter を参考に、 $ join -1 1 -o 0 2.2 2.3 -a 1 -e "0 PASSWORD0" <(sort File1) <(sort File2) とやってみたところ、 ji**@yahoo.jp 0 PASSWORD0 0 PASSWORD0 hana**@yahoo.jp 2 password2 ta**@yahoo.jp 1 password1 と、ji**のレコードにカラム2、3が2回繰り返して表示されてしまいます。 二重引用符を外すと「join: 余分な演算子 '/dev/fd/62' と、原因不明のエラーが表示され、また、-e 0 -e PASSWORD0 と言う構文もエラーとなります。 ji**@yahoo.jp 0 PASSWORD0 hana**@yahoo.jp 2 password2 ta**@yahoo.jp 1 password1 と表示してくれたら解決なのですが、どう指定すれば正常な結果が得られるでしょうか?

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

  • ベストアンサー
  • kteds
  • ベストアンサー率42% (1876/4424)
回答No.1

>CentOS7のjoinコマンドで・・・ CentOS7に限らずLinuxのjoinコマンドでは出力フィールドに-eオプションの対象フィールドが複数(今回は2つ)あるとそのようになってしまいます。 したがって、デリミッタをspaceではなくて、例えばカンマ区切りとして、 ”0 PASSWORD0" を1文字列として扱えば可能です。(デミリッタを指定しないと space がデリミッタとみなされますので1 password1 や 2 password2 は2文字列となってしまいます。) つまり、<File2>は ta**@yahoo.jp, 1 password1 hana**@yahoo.jp, 2 password2 のようにカンマ区切りとして -t, でカンマ区切りを指定して $ join -t, -1 1 -o 0 2.2 -a 1 -e "0 PASSWORD0" <(sort File1) <(sort File2) のようにしてはどうでしょうか。 結果は ji**@yahoo.jp, 0 PASSWORD0 hana**@yahoo.jp, 2 password2 ta**@yahoo.jp, 1 password1 のようになります。 どうしても結果のカンマをspaceにしたければ、別のコマンドでspaceに置き換えればいいでしょう。

Turip_Marlowe
質問者

お礼

〉 -eオプションの対象フィールドが複数あるとその様になってしまいます。 矢張りそうだったんですね、そうなのかなと思って翻訳サイトに手伝ってもらいながら 'coreutils@gnu.org' に仕様確認したところです。 いただいたご回答はなるほどですね。 入力ファイルのフォーマットは変更できないので、応用させていただき、-tのパラメータを"0,PASSWORD0"でやってみます。.を後でスペースに変更します。 大変助かりました。ありがとうございました。

その他の回答 (1)

  • kteds
  • ベストアンサー率42% (1876/4424)
回答No.2

No.1です。 OKWaveの担当者が質問文、回答文の一部の文字を勝手に書き換えたようです。

Turip_Marlowe
質問者

お礼

私の質問は「実際に存在するかも知れないメールアドレスについて、マスキングいただいただけで、むしろ私が投稿する時に気付くべきでした。 それとNo.1のお礼で書いた「スペースとカンマを入れ替える」と言うのは無理ですね。 どうせsortを使ってますので、 $ join -j 1 -o 0,2.2,2.3 -a 1 -e EMPTY <(sort File1) <(sort File2) | sed 's/EMPTY EMPTY/0 PASSWORD0/' とsedで逃げることにしました。

関連するQ&A

  • C言語でのCSVソートとデータ抽出について

    皆様、はじめまして。 この度、急ぎでプログラムをC言語で作成するように命じられました。 C言語は経験が無いと断ったのですが、要員確保が出来ない為、何とかしてくれとのこと。 本来なら自分で学習しながら、作成すべきなのですが、超短納期の為、その時間が取れません。 今回は誠に申し訳ないのですが、皆様のお力をお借り出来ないでしょうか。 宜しくお願いいたします。 仕様概要 ・CSVファイルを読み込み、2カラム目の項目(文字型)で昇順ソート(qsort)を行う。 ・ソートされた2カラム目の同一値毎に1カラム目(数値型)が最大値となるレコードを抽出する。 ・抽出されたレコードを新規CSVファイルに出力する。 入力CSV概要 ・レコード件数は日によって変わる ・カラム数は8つ ・各カラムの項目長は可変長 ・上記に伴いレコード長も可変長 入力ファイル例 39,"AAA3","B1","C1","D1","E1","F1","G1" 100,"AAA1","B2","C2","D2","E2","F2","G2" 101,"AAA2","B3","C3","D3","E3","F3","G3" 105,"AAA1","B4","C4","D4","E4","F4","G4" 102,"AA1","B5","C5","D5","E5","F5","G5" 99,"AAA2","B6","C6","D6","E6","F6","G6" 1019,"AAA3","B7","C7","D7","E7","F7","G7" 処理後に出力されるファイル 102,"AA1","B5","C5","D5","E5","F5","G5" 105,"AAA1","B4","C4","D4","E4","F4","G4" 101,"AAA2","B3","C3","D3","E3","F3","G3" 1019,"AAA3","B7","C7","D7","E7","F7","G7"

  • MySQLで複数データベースの検索/ソートについて

    お世話になっております。 PHP4.4.1+MySQL4.1.15を使用しております。 複数のデータベースに含まれる複数のテーブルをひとつの大きなテーブルとして検索/ソートする方法はありませんでしょうか? 結合ではなく、全レコードを全て単体として検索/ソートをかけたいのです。 それぞれのデータベースに含まれるテーブルに、共通の項目があり、その共通の項目順にソートしたり、絞込をかけたりしたいのですが、調べてみても、どうしても結合(JOIN)に行き着いてしまいます。 JOINによる結合だと、共通の項目以外のレコードが表示されないので、これでは意味をなしません。 ご教授の程、お願い致します。

    • ベストアンサー
    • MySQL
  • joinの-eオプション

    joinの-eオプション 表題そのままですが、joinの-eオプションは 入力が無い場合の文字を決定するとありますが、 いろいろ試してみましたが、使い方がわかりません。 $cat tes1 1 2 3 4 5 6 #cat tes2 1 10 2 20 4 40 のようなファイルを 1 10 2 20 3 0 4 40 5 0 6 0 のように結合したいと思っています。 -e のオプションで可能でしょうか? もし不可能ならどのような方法があるでしょうか?

  • OUTER JOIN とgroup by

    こんにちは。 mysqlのselect文なのですが、LEFT OUTER JOIN した右側をgroup byし、そのなかで最大値を持つものを結び付けたいのですが、四苦八苦やってみたところ2日ほど解決できず・・・。 どなたかご教授いただけますと助かります。 テーブルなどは以下の通りです。 ---tableA----(テーブル名) user / supplier(カラム名、以下レコード) 1 / 1 1 / 2 1 / 3 2 / 1 2 / 3 ---tableB--- skuno / supplier / update_at 1 / 1 / 2011-12-12 2 / 1 / 2011-12-13 3 / 1 / 2010-11-10 検索の目的は、特定のカラムuserに対応する(例えばuser = 1)supplierの値(1,2,3)を取り出し、tableBにおいて、それぞれの値に結びつくskunoのうち最新のupdate_atを持つskunoを取り出したいというものです。 上記の例の場合、希望する検索結果は以下のような想定です。 supplier / skuno 1 / 2 2 / null 3 / null 私が検討してみたsql文は以下の通りなのですが、 select supplier,skuno from tableA LEFT JOIN tableB ON tableA.supplier = tableB.supplier where tableA.user = 1 and tableB.update_at IN (select max(update_at) from tableB group by supplier) group by tableA.supplier; この場合だと、右側がnullだとsupplierの値が表示されず、 supplier / skuno 1 / 2 となってしまいます。 select supplier,skuno from tableA LEFT JOIN tableB ON tableA.supplier = tableB.supplier where user = 1 group by supplier; だと右側のテーブルの値が指定できず・・・ ここからどのように条件付けをしたらよいのか、お力添えをいただけますと幸いです。 よろしくお願い申し上げます。

    • ベストアンサー
    • MySQL
  • ListViewについて

    CSVファイルを読込後、指定したカラムにてソートをかけてからListViewに表示することは可能でしょうか???

  • Windows上でcentos仮想環境について

    下記のサイトを参考にcentos仮想環境を作製することに成功しました。 http://www.e-agency.co.jp/column/20121004.html geditテキストエディタでc言語を書きコンパイルを試みたのですが bash: a.out: コマンドが見つかりません と表示され、プログラムが実行されません。 デスクトップ上にはa.outのファイルがあるのですが上記の様に表示されてしまいます。 どうすればプログラムが動くでしょうか? ご協力よろしくお願いします。

  • MySQLのUPDATE文について

    以下のようなスクリプトを書いた時に、phpMyAdminで、テーブルの中身をみると、 photo カラムには、添付画像ファイルのファイル名の値が入っているのに、 bbs.php側からアップデートしようとすると、ip_add以下passwordまでのカラムの 中身が空なのです。SQLの文法的に何かまちがってるでしょうか? 一応、ラストレコードのカラムを更新することを念頭に置いておりますが。 <file_upload.php> $sql = "INSERT INTO bbstbl_test (photo) VALUES('$upfilename');"; -------------------------------------------------------------------------------- <bbs.php> $sql = "UPDATE bbstbl_test SET ip_add = $ip_add, date = $date, name = $name, email = $email, title = $title, message = $message, password = $password;";

    • ベストアンサー
    • PHP
  • 複数テーブルからLIKE検索を行いたいのですが、う

    複数テーブルからLIKE検索を行いたいのですが、うまくいかないので教えてください ■やりたいこと ・一つのキーワードで、MAINテーブル「hoge」カラムと、SUBテーブル「hoge」カラムを検索して、該当したレコードを表示したい ■テーブル構成 ・MAIN … 「id」「main1」「hoge」… ・SUB… 「sub_id」「main_id」「sub1」「hoge」… ・1つの「id」に対して、対応する「sub_id」が複数(「id」1は一つだけ。対応する「sub_id」1は複数あります) ■試したこと1 SELECT a.* , r.* FROM main a LEFT JOIN sub r ON a.id = r.main_id WHERE ( a.hoge LIKE '%キーワード%' OR r.hoge LIKE '%キーワード%' ) とやると、2件ヒットするはずなのに、1レコードしか取得できません(1レコードに「hoge」カラムが2つ入ります) ■試したこと2 SELECT a.* , r.hoge as rhoge FROM main a LEFT JOIN sub r ON a.id = r.main_id WHERE ( a.hoge LIKE '%キーワード%' OR r.hoge LIKE '%キーワード%' ) とやると、2件ヒットするはずなのに、1レコードしか取得できません(1レコードに「hoge」と「rhoge」カラムになります) ■試したこと3 FROMで2箇所指定するのかと思ったのですが、 SELECT a.* , r.* FROM (main a,sub r) LEFT JOIN r ON a.id = r.main_id WHERE ( a.hoge LIKE '%キーワード%' OR r.hoge LIKE '%キーワード%' ) 結果は、#1066 - Not unique table/alias: 'r'になります ■試したこと4 LEFT JOINがいらないのかと思い、削除したら、2件ヒットするはずなのに、たくさんヒットしてしまいます ■質問 欲しいのは、キーワード検索した際、該当カラムにヒットした数だけのレコードなのですが、どうすれば良いのでしょうか? ■例 ・東京で検索 ・MAINテーブル「hoge」カラム(2レコード)で2ヒット ・SUBテーブル「hoge」カラム(3レコード)で3ヒット ・ヒットした該当5レコードを取得したい

    • ベストアンサー
    • MySQL
  • ソートが重い

    掲示板で記事数が一万件越えたあたりからソートなどでの一覧表示が重くなりました。 ※10記事のレコード一覧表示だけで20秒ほど。 5000記事くらいまではサクサク動いてた気がするんですが、そんなもんなんでしょうか? カラムは10個くらいです。コメント上限文字数は2千字程度です。 改善策があれば宜しくお願いします。

  • c#のメソッドjoinが機能しない

    Microsoft visual C#2005でスレッドを使用したプログラムを行なっているのですが,意図した動作を行えません. 意図する動作は,連番で複数の画像を持つ二つのフォルダ(0,1とします)から画像をリストに読み込み,フォルダ0読み込み→フォルダ0内の画像を順に続けて表示(この間にフォルダ1の読み込み)→3秒置いて→フォルダ1内の画像を順に続けて表示です.     //再生ボタン private void button_Click(object sender, EventArgs e) {       //フォルダ0読込 directory = directories[0]; Read = new Thread(new ThreadStart(read_image)); Read.Start(); if(now_loading == true) { Read.join(); } //フォルダ0表示 Showing1 = new Thread(new ThreadStart(Show)); Showing1.Start(); //フォルダ1読込 directory = directories[1]; Reads = new Thread(new ThreadStart(read_images)); Reads.Start(); }       if(now_showing == true) { Showing1.Join(); } if(now_showing == true) { Reads.Join(); } //フォルダ1表示 Showing2 = new Thread(new ThreadStart(Show)); Showing2.Start(); }     //動画表示 private void Show() { Stopwatch sw = new Stopwatch(); //リストに入っているファイルの数をfile_numbersに入れる file_numbers = img.Count; //1枚目を表示 pictureBox1.Image = img[0]; //フレーム番号のリセット now_show = 1; //時間計測:開始 sw.Start(); while (now_show < file_numbers) { if (33 <= sw.ElapsedMilliseconds)//一枚の表示時間が33ミリ秒以上になったら次の画像を表示 { //前フレームを消去 img[0].Dispose(); img.RemoveAt(0); //画像を表示 pictureBox1.Image = img[0]; //カウントを進める now_show++; //時間計測再スタート sw.Reset(); sw.Start(); } } //時間計測:停止 sw.Stop(); //最終フレームを消去 pictureBox1.Image = null; img[0].Dispose(); img.RemoveAt(0); Thread.Sleep(3000);//3秒待機 } //読込 private void read_images() { int read_numbers = Directory.GetFiles(directory).Length; now_loading = true; for (int i = 0; i < read_numbers; i++) { img.Add(Image.FromFile(String.Format("{0}\\{1:000}.jpg", directory, i))); } now_loading = false; } //初回読込 private void read_image() { now_loading = true; //フォルダ内のファイル数の取得 file_numbers = Directory.GetFiles(directory).Length; //画像ファイルを読み込む img = new List<Image>(); for (int i = 0; i < file_numbers; i++)//ファイル数の数 { img.Add(Image.FromFile(String.Format("{0}\\{1:000}.jpg", directory, i))); } now_loading = false; } joinでスレッドの終了を待つということなので,B表示スレッドを開始する前に A表示スレッド.join を置けばよいと考えたのですが,タイマーを配置して見たところA表示のスレッドのjoinを待つ前にB表示のスレッドが始まってしまっているようです.(Show内の始めと終わりの部分でテキスト表示すると,フォルダ1の再生後にフォルダ0のShowスレッドが終了していました) また,各画像フォルダの再生時間もタイマで図るとほぼ指定した通りなのですが自分の時計で計測すると画像500枚で2秒程度短くなってしまいます. joinを使っている時点で表示スレッドを関数にした方が良いのかもしれませんが,何故思うように動かないのか知りたいです. アドバイス頂けると嬉しいです.