質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

Q&A

解決済

3回答

1474閲覧

ばらばらな名前が付いたファイルのデータにファイルの通しIDを付与してまとめたい。

watergames-_-

総合スコア23

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

0グッド

0クリップ

投稿2016/07/30 10:37

編集2016/07/30 10:58

一部修正しました。行と列の記載の誤記を修正し、データの追加をしました。

###前提・実現したいこと
100個のばらばらな名前(A)が付いたファイル(file1)があります。
これらのファイルには10,000行位のデータ(B)があります。
これと別にこの100個のファイル名(A)が3列目に、ID番号(C)が1列目に書かれたファイル(file2)があります。

この100個のファイル(A001100)の1行づつ(B)にID番号(C001100)を付与して、一つのファイルにまとめたいのですが、
やり方に困っています。
file2の3列目を読んで、そのファイル名を元にファイルAを1行目から読み込み、
file2の1列目に書かれているIDをくっつけていくという作業です。
目的ファイルのイメージとしては下記の様な感じです。

C001 B001
C001 B002
C001 B003
...
C002 B001
C002 B002
C002 B003
C002 B004
C002 B005
...
C100 B001
C100 B002
C100 B003
といった感じです。

for loopを使うことでどうにか出来そうな気がするのですが、
上手く処理出来ません。
下記を試しましたが、正直後半は自分でも何をやっているのか分かっていない状態です。アドバイス頂ければ幸いです。

他の方法として、上記のfile2(1oo個のファイル名(A)が3列目に、ID番号(C)が1列目に書かれたファイル)をもとに、ファイル名を先に換えてしまう方が簡単かも知れませんので、そのやり方でも結構です。
宜しくお願いします。

###試したソースコード

sh

1for f in `awk '{print $3}' file2` ; do 2 while read line; do 3 for i in `awk '{print $1}' file2`; do 4 echo "$i $line"; 5 done <"$f"; 6 done > file3; 7 done

###ファイルの中身
ご指摘頂いたので、ファイルの実際の中身を一部載せます。
file2はこんなファイルです。3列目がファイル名です。

ID_001 6d822383-e59b-41a6-8680-6bc3f4d1e862 480de2f2-6f01-43e9-bc1b-77b8ec8451f5.txt 4804a20f7c4979dfbc4a25039163b7d6 538584 submitted ID_002 bff3f31e-ee05-448d-af36-1ab183ba2ff4 fcd43085-7338-43fe-bc25-9d87b04e227f.txt 29096eca2f55808fa19cf849107e8f8e 541634 submitted ID_003 c640cec0-1656-4ca2-92a0-afca1cf3f86c e38e0ced-093c-44e9-9f3b-7cdd0e6b912e.txt 75a590b047e61327b56b32d88175cdce 549556 submitted ID_004 8577ad66-1a2d-41df-99c8-ba6b4a5399ac 2e33a2c5-2196-49c4-866a-34b12d984c15.txt 8235f4a52239fe40439028f713e515c0 508395 submitted ID_005 b826b9fc-3287-41cc-8e29-72666d2fa4f8 939eeb3c-9c0b-431f-8020-7165ee19f068.txt 35001fba081a7a8b9bba35f7a92be9b9 506780 submitted ID_006 d1b58025-d1cc-46ef-b9cb-6f0315a5620d e5214aa1-432a-4a47-886c-3ded1616255b.txt 905ca9f1688037beb3b77fce133a009c 524393 submitted ID_007 6543a250-d902-4612-b64e-18404944ca3d 3828d55b-81ae-42b2-8f5e-d1dcd87e576a.txt b0ea16a0c6cf2628f77acfd182e71195 534881 submitted ID_008 f68912b3-1117-4793-a492-2804c7c903de 8a799dfa-c1b5-4b13-9c91-6cbfe2abbc9f.txt 3221205f01a00db20d713d3c16cc8d47 543383 submitted ID_009 ef3a8b0a-0ce7-4d26-98cc-7e78c21db36b 09a677f2-d81d-4c3f-adf9-f8594e064e44.txt dac19654887b2cfb081f3c5f82c8f3fa 483745 submitted ID_010 6a8e84dc-306b-4752-95d7-d653fe91f3a3 f748bf78-4dc1-47ad-8611-8186479d3e4b.txt b3d8f563268ed14daf59d9598b169d69 525039 submitted ID_011 4403f1cf-51f6-45bb-8eea-2a4ee08a803c 2eaa996b-267f-4c9c-a58e-d1759c27c46c.txt b18798c0786f15af3a0734dadae8cc19 525766 submitted

file1は例えば480de2f2-6f01-43e9-bc1b-77b8ec8451f5.txt
といったファイル名で中身は下記の通りです。

0.0679637658767 0.00471509417358 2.7638655666 0.0 4.21007764058 18.1976585455 0.0 0.141924334625 76.4268070169 0.140819865095 0.0 0.0 0.0 28.6577220146 0.0338151883479 1.77092901396 8.68206352022 0.0 0.0 6.47409128452 0.0

最終的に欲しいのはこんな感じのファイルです。

ID_001 0.0679637658767 ID_001 0.00471509417358 ID_001 2.7638655666 ID_001 0.0 ID_001 4.21007764058 ID_001 18.1976585455 ID_001 0.0 ... ID_002 1.77092901396 ID_002 8.68206352022 ID_002 0.0 ID_002 0.0 ...

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asahina_dev

2016/07/30 10:41

元データのサンプルファイルを書くべき
guest

回答3

0

皆さんと異なるものに敢えてしました。sed方が良いとは思ってます。

bash

1while read -a arr; do 2 awk -v ar=${arr[0]} '{print ar,$0}' ${arr[2]} >>file3 3done<file2

ご説明不足にて失礼いたしました。

bash

1while read -a arr;do 2    #whileのreadにてfile2を変数arrに読み込みます。1行づつ 3    #その際whileに-aを付ける事でarrに配列として値がセットされます。 4    #file2は空白でセパレートされているのでデフォルトで分離されます。 5    #他の場合,であればIFSで変更できます。 6    #${arr[0]},${arr[1]},${arr[2]}に値file2の値がセットされます。 7 8 awk -v ar=${arr[0]} '{print ar,$0}' ${arr[2]} >>file3 9 #awkの内部の変数arに値を設定する為に-vを使います。${arr[0]}をar変数に渡します。 10 #${arr[2]}はファイル名が展開(awk実行前)されますので awkの入力ファイルとなります。<file2 11 #awkでは$0で入力ファイル行の全体を示しています、その前にarr変数値をつけます。 12 #arr,$0とカンマを入れると空白間に付けて出力します,カンマで無く空白だと結合し出力されます。 13 #print出力は>>でfaile3へ追加します。 14 15done<file2 16    #whileへの入力ファイルとします。

読み方のポイントは、bashが必ず先に処理を行った後にawkが実行される事に有ります。bashにとってはawkはただのコマンドです。whileにてfile2の行数分awk実行されます。
さらに速度を求めるのであればfile2の読込みもawkで全て行うと早なると思います(修正大変ですが)。bashのloopは速度が出ないので。

言った手前書きました旨く行くとよいのですが・・・

awk

1awk '{cc=$1;ff=$3;while(getline <ff >0){print cc,$0;}}' file2 >>file3

投稿2016/07/30 14:48

編集2016/09/22 05:01
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

watergames-_-

2016/07/31 10:15

ありがとうございます。 上手くいきました。1.7MBのファイル180個くらいで合計350MB位のファイルになるのですが、一番速かったです。
watergames-_-

2016/09/21 16:03

古い質問の続きで申し訳ありません。 回答頂いたときに何をしているのか良く分からなかったのですが、awkを少し調べれば分かるものと思っていました。 でも、色々調べても何でうまくいくのかさっぱり分かりません。 お手数お掛けしますが、それぞれ何をしているのか解説して頂けないでしょうか? 宜しくお願いします。
watergames-_-

2016/09/22 08:00

ありがとうございます! とてもわかりやすかったです。すっきりしました。 readのaオプション説明が持っている本やwebページには無く、arr[0]が$0と同じように行全部を示すのかと思っていました。 全部awkでやるものも上手く動きました。 あまりにも速くて失敗したかと思ったぐらいでした。 また宜しくお願いします。
guest

0

ベストアンサー

自分もノーテストなんで。(^_^;

Sh

1awk '{print $1,$3}' file2 | \ 2while read id fn 3do 4 sed "s/^/$id /" $fn >>file3 5done

投稿2016/07/30 11:32

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

watergames-_-

2016/07/30 11:51

ありがとうございます。 うまくワークしました! もう少し、皆さんのやり方を参考にさせて頂きたいので質問をクローズせずにおかせてください。
guest

0

タイポしてたらごめんなさい。(ノーテスト)

bash

1file1=$1; # file1.txt 2cat $file1 | while read line; 3do 4 id=$( echo $line | cut -d '\t' -f 1); 5 file2=$(echo $line | cut -d '\t' -f 3); 6 7 for line2 in $(cat $file2); 8 do 9 echo $id $lien2; 10 done; 11done;

多分TSVだとみたので '\t' になってますが スペース区切りなら ' ' にしてください。

処理概要

  1. ファイル1を設定(引数化のため)
  2. 1行ずつ処理

4.その行の id を取得
5.その行の file2 を取得
7.ファイル2をループ
9.出力形式を指定して出力

※ sh ファイル化して リダイレクトして file3 に出力してください。

投稿2016/07/30 11:19

編集2016/07/30 11:24
asahina_dev

総合スコア610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

watergames-_-

2016/07/30 12:13

ありがとうございます。 基本的には上手くいきました。 ただ、file1が1列じゃなくて2列になった場合は、 ID、1列目、2列目ではなくて ID、1列目 ID、2列目 となってしまいました。
asahina_dev

2016/07/30 12:25

その場合は file2 でも `id` `file2` をとるような処理を追加してください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問