ひとつ前のエントリの中で、2つのリストをCROSS JOINする、ということを行っています。
データの流れ
[tmp.key1]
[tmp.key2]
上記二つのファイルをCROSS JOINしたような感じで、下記の出力を得ます。
1
2
3
4
5
6
7
8
9
|
A,Ice
A,Juice
A,OREO
B,Ice
B,Juice
B,OREO
I,Ice
I,Juice
I,OREO
|
シェルスクリプトでどう書くか
- 普通のやり方 ・・・ **while**を使う
- tmp.key1の各行に対し、tmp.key2の内容をくっつけて出力する、という2重ループを形成します
1
2
3
4
5
6
|
cat tmp.key1 | while read L1 ; do
cat tmp.key2 | while read L2 ; do
echo $L1,$L2
done
done
|
- **xargs**を使ったやり方
- **bash**コマンドを利用して、**xargs**をネストさせる
1
2
|
cat tmp.key1 | xargs -I% bash -c 'cat tmp.key2 | xargs -I@ echo %,@'
|
ここで、bashを使用せず普通にxargsをパイプしてしまうと、思ったような出力が得られません。
1
2
|
cat tmp.key1 | xargs -I% cat tmp.key2 | xargs -I@ echo %,@
|
↓
1
2
3
4
5
6
7
8
9
|
%,Ice
%,Juice
%,OREO
%,Ice
%,Juice
%,OREO
%,Ice
%,Juice
%,OREO
|
※下記のような動きになってしまうイメージです
1
2
|
(cat tmp.key1 | xargs -I% cat tmp.key2) | xargs -I@ echo %,@
|
また、ここで、括弧の位置を変えても
```
$ cat tmp.key1 | xargs -I% (cat tmp.key2 | xargs -I@ echo %,@)
bash: 予期しないトークン `(' 周辺に構文エラーがあります
1
2
3
4
5
6
|
とエラーになってしまいます。<br/>
(xargsに渡すのは式じゃなくてコマンドだから、なのかな)<br/>
<br/>
というわけで、**bash**コマンドを渡してやります。<br/>
**bash**コマンドにコマンドを渡すには、-c オプションを使用します。
|
-c string If the -c option is present, then commands are read from
string. If there are arguments after the string, they are
assigned to the positional parameters, starting with $0.
1
2
3
|
<br/>
なので、後半の処理「cat tmp.key2 | xargs -I@ echo %,@」の部分を -c の string として渡してやって、
|
cat tmp.key1 | xargs -I% bash -c 'cat tmp.key2 | xargs -I@ echo %,@'
1
2
3
4
5
6
|
とするとうまくいきます。<br/>
以上。まとまったかな。
|