まあ、問題はそれより少し複雑です。
2つのファイルがあります。ファイル1そしてファイル2、それぞれ次のデータが含まれます。
name of the game, hours spent playing it, last 7 days
ファイル1:
game1 100 20
game3 40 5
ファイル2:
game1 90 25
game4 40 2
ターゲット:
両方のファイルにゲームがある場合は、ゲームをプレイするのに費やされた時間を減算します。ファイル1 - ファイル2
ゲームしかない場合ファイル1、表示するがオリジナルとして(ファイル1 - 0)
ゲームしかない場合ファイル2、表示するが元の否定として表示(0 - ファイル 2)
どうすればいいですかbash
?
答え1
ファイルがソートされていると仮定すると、カフの回答から外れます。
awk '{$2= -$2; $3= -$3} 1' file2 |
join -a1 -a2 file1 - |
awk 'NF > 3 {$2+=$4; $3+=$5; NF=3} 1'
入力の出力を提供します。
game1 10 -5
game3 40 5
game4 -40 -2
(ファイルがソートされていない場合は、ソートしてソートされたままにします。これにより、作業が簡単になります。)
これだけPOSIXの特徴join
そしてAwkのPOSIX機能、ほぼどこでも動作します。
$2
awkには2番目のフィールドへの参照があります。 $3
3番目のフィールド(処理中のファイルの各行)への参照。 1
中かっこの外側に現れるのは{...}
単に「真」を意味するので、その行を印刷する基本的な操作が行われます。
本質的に、最初のAwkコマンドは数値を負の数file2
に置き換えます。
このjoin
コマンドは、file1
標準入力(Awkから受け取った内容)で指定されたテキストにリンクされます。コマンドでは、次は-
(他のファイル名ではなく)「標準入力の使用」を意味します。オプションとは、最初または2番目のファイルからペアリングできない行があるまま出力されることを意味します。file1
join
-a1
-a2
最後の Awk コマンドはペアの行をとります。窒素数量Fフィールドが3()より大きく、NF > 3
4番目のフィールドを2番目のフィールドに追加し、5番目のフィールドを3番目のフィールドに追加して、4番目と5番目のフィールドを切り捨てます。
同様に、最後の1
外部中括弧は、Awkのデフォルト動作である「print」を実行するために使用されます。
(望むよりこのチュートリアルもっと学び、Awkを正しく学びましょう。 )
ここでは多くのことが起こっています。次のセクションを追加する前に、このコマンドの各セクションを実行することをお勧めします。最初:
awk '{$2= -$2; $3= -$3} 1' file2
そしてこれを研究して理解してください。それから:
awk '{$2= -$2; $3= -$3} 1' file2 |
join -a1 -a2 file1 -
そしてこれを研究して理解してください。 (-a1
およびフラグを省略する-a2
か、そのうちの1つだけを省略してみてください。)
次に、完全なコマンドを使用します。
awk '{$2= -$2; $3= -$3} 1' file2 |
join -a1 -a2 file1 - |
awk 'NF > 3 {$2+=$4; $3+=$5; NF=3} 1'
もっと意味があるか見てください。
答え2
エレガントではありませんbash
、、、join
牛に似た一種の栄養 sed
変形:
join -a1 -a2 -o 0 1.2,2.2,1.3,2.3 file1 <(sed 's/ \([0-9]*\)/ -\1/g' file2) | \
sed 's/ -/-/g;s/[0-9]*-[0-9]*/$((&))/g;s/.*/echo &/eg'
出力:
game1 10 -5
game3 40 5
game4 -40 -2