与えられた入力を使って次の出力を取得しようとしています。コマンドで実行できますかdiff
?この構文を試していますが、動作しません。
diff -a --suppress-common-lines a.txt b.txt
以下は2つの入力ファイルです。
最初a.txt
:
abc abc/d_4.1/efg 35
xyz abc/d_4.1/efg 36
mno abc/d_4.1/efg 38
そしてb.txt
:
abc abc/d_4/efg 35
xyz abc/d_4/efg 36
mno abc/d_4/efg 40
この出力が必要です(以下は2つのファイルの出力ですdiff
)。d_4.1
d_4
mno abc/d_4.1/efg 38
mno abc/d_4/efg 40
答え1
ユーティリティにはdiff
フィールドをスキップするオプションはありません。
カット&uniqで動作しようとしています。以下のアプローチがうまくいくと思いますが、出力に列2がありません。
$ cut -d/ -f1,3 file1 file2 |sort |uniq -u #column 2 is skipped
より正確な解決策として、次のawkを提案します。
awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2
与えられた入力データの各行の末尾に余分なスペースが含まれているため、フィールド区切り文字のスペースまたはスラッシュ/を使用します。
実際のデータに余分なスペースがなくても、上記の解決策はまだうまく機能します。
awkの論理は次のとおりです。中間列(/d_4/
)をスキップしてuniq -uをシミュレートします。
file1とfile2の間のすべての一意の行(awkで連結)のみを印刷します。
テスト(オンラインテストもご覧ください)
cat file1
cat file2
echo "awk start:"
awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2
echo "awk end"
#Output
#file1
abc abc/d_4.1/efg 35
xyz abc/d_4.1/efg 36
mno abc/d_4.1/efg 38
#file2
abc abc/d_4/efg 35
xyz abc/d_4/efg 36
mno abc/d_4/efg 40
awk start:
mno abc/d_4/efg 40
mno abc/d_4.1/efg 38
awk end
答え2
awk
、および分割onを使用すると、/
このコードは最初のフィールドが一致し、3番目のフィールドが一致しないときに2行を印刷します。
パスワード:
#!/bin/awk -f
BEGIN { FS = OFS = "/" }
$1 in a2 && $3 != a2[$1] {
print $1, a1[$1], a2[$1]
print
}
{
a1[$1] = $2
a2[$1] = $3
}
結果:
$ awk -f test.awk file1 file2
mno abc/d_4.1/efg 38
mno abc/d_4/efg 40