
2つのファイルがあります。
ファイル1:
Dave 734.838.9800
Bob 313.123.4567
Carol 248.344.5576
Mary 313.449.1390
Ted 248.496.2204
Alice 616.556.4458
ファイル2:
Bob Tuesday
Carol Monday
Ted Sunday
Alice Wednesday
Dave Thursday
Mary Saturday
2つのファイルをマージしました。
file3 は次のようになります。
Name On-Call Phone
Carol MONDAY 248.344.5576
Bob TUESDAY 313.123.4567
Alice WEDNESDAY 616.556.4458
Dave THURSDAY 734.838.9800
Nobody FRIDAY 634.296.3356
Mary SATURDAY 313.449.1390
Ted SUNDAY 248.496.2204
しかし、私は一日のルーチンを体系的に整理することはできません。どうすればいいですか?
答え1
他の方法は次のとおりです(短いバージョン、一時ファイルはありません)。
{ printf %s\\n "Name On-Call Phone";
join -a1 -j2 -o 1.1 2.1 1.2 2.3 -e "Nobody" \
<(printf %s\\n '5 Friday' '1 Monday' '6 Saturday' '7 Sunday' '4 Thursday' '2 Tuesday' '3 Wednesday') \
<(join <(sort file2) <(sort file1) | sort -k2) | sort -k2n | sort -k1n | \
cut -d' ' -f 2-; } | column -t
大文字の日付名が必要な場合は、次のようにします。
{ printf %s\\n "Name On-Call Phone"; join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(cat <<IN
5 Friday FRIDAY
1 Monday MONDAY
6 Saturday SATURDAY
7 Sunday SUNDAY
4 Thursday THURSDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
IN
) <(join <(sort file2) <(sort file1) | sort -k2) | sort -k2n | sort -k1n | cut -d' ' -f 2-; } | column -t
長いバージョン:
2つのファイルがあるとしましょうfile1
。
Dave 734.838.9800
Bob 313.123.4567
Carol 248.344.5576
Mary 313.449.1390
Ted 248.496.2204
Alice 616.556.4458
Jimmy 324.555.8867
Harry 422.858.2354
Lou 788.907.6859
そしてfile2
:
Bob Tuesday
Carol Monday
Jimmy Wednesday
Ted Sunday
Alice Wednesday
Dave Thursday
Harry Monday
Mary Saturday
Lou Sunday
私たちが作ったものは次のとおりですfile3
。
1 Monday MONDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
4 Thursday THURSDAY
5 Friday FRIDAY
6 Saturday SATURDAY
7 Sunday SUNDAY
次に、次を実行します。
{ printf %s\\n "Name On-Call Phone"; \
join <(sort file2) <(sort file1) | sort -k2 | \
join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) - \
| sort -k1n | cut -d' ' -f 2-; } | column -t
または1行:
{ printf %s\\n "Name On-Call Phone"; join <(sort file2) <(sort file1) | sort -k2 | join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) - | sort -k1n | cut -d' ' -f 2-; } | column -t
出力:
Name On-Call Phone
Carol MONDAY 248.344.5576
Harry MONDAY 422.858.2354
Bob TUESDAY 313.123.4567
Alice WEDNESDAY 616.556.4458
Jimmy WEDNESDAY 324.555.8867
Dave THURSDAY 734.838.9800
Nobody FRIDAY Nobody
Mary SATURDAY 313.449.1390
Lou SUNDAY 788.907.6859
Ted SUNDAY 248.496.2204
仕組み:
join <(sort file2) <(sort file1) | sort -k2
- 最初の2つのファイルは2番目のフィールドに基づいて接続され、次に出力は2番目の列に基づいてソートされます。
Carol Monday 248.344.5576
Harry Monday 422.858.2354
Mary Saturday 313.449.1390
Ted Sunday 248.496.2204
Lou Sunday 788.907.6859
Dave Thursday 734.838.9800
Bob Tuesday 313.123.4567
Jimmy Wednesday 324.555.8867
Alice Wednesday 616.556.4458
これは、2番目のフィールドに基づく結合join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) -
にパイプされます。 file3の不一致行が出力に追加され、欠落している出力フィールドが次に置き換えられます。file3
-a1
-e "Nobody"
"Nobody"
5 Nobody FRIDAY Nobody
1 Carol MONDAY 248.344.5576
1 Harry MONDAY 422.858.2354
6 Mary SATURDAY 313.449.1390
7 Ted SUNDAY 248.496.2204
7 Lou SUNDAY 788.907.6859
4 Dave THURSDAY 734.838.9800
2 Bob TUESDAY 313.123.4567
3 Jimmy WEDNESDAY 324.555.8867
3 Alice WEDNESDAY 616.556.4458
結果は再パイプされ、sort -k1n | cut -d' ' -f 2-
最初のフィールドの出力を数値でソートし、最初のフィールドを削除します。
Carol MONDAY 248.344.5576
Harry MONDAY 422.858.2354
Bob TUESDAY 313.123.4567
Alice WEDNESDAY 616.556.4458
Jimmy WEDNESDAY 324.555.8867
Dave THURSDAY 734.838.9800
Nobody FRIDAY Nobody
Mary SATURDAY 313.449.1390
Lou SUNDAY 788.907.6859
Ted SUNDAY 248.496.2204
{...}
印刷ヘッダーと一緒にグループ化されているため、printf %s\\n "Name On-Call Phone"
出力全体がパイプで接続され、column -t
美しく表示されます。
sort
file3がすでに2番目の列にソートされている場合は、1つをスキップできます(たとえば、今回は単純な2列file3を使用)。
5 Friday
1 Monday
6 Saturday
7 Sunday
4 Thursday
2 Tuesday
3 Wednesday
"Nobody"
たとえば、次のように電話番号を割り当てますsed 's/Nobody/888.000.8888/2'
。
{ printf %s\\n "Name On-Call Phone"; join <(sort file2) <(sort file1) | \
sort -k2 | join -a1 -j2 -o 1.1 2.1 1.2 2.3 -e "Nobody" file3 - | sort -k1n | \
cut -d' ' -f 2-; } | sed 's/Nobody/888.000.8888/2' | column -t
出力:
Name On-Call Phone
Carol Monday 248.344.5576
Harry Monday 422.858.2354
Bob Tuesday 313.123.4567
Alice Wednesday 616.556.4458
Jimmy Wednesday 324.555.8867
Dave Thursday 734.838.9800
Nobody Friday 888.000.8888
Mary Saturday 313.449.1390
Lou Sunday 788.907.6859
Ted Sunday 248.496.2204
答え2
awk '
BEGIN {
print "Name On-Call Phone"
split("MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY", days);
}
NR == FNR { day[$1] = $2; next }
{ lines[toupper(day[$1])] = $1 OFS toupper(day[$1]) OFS $2 }
END {
for (i=1; i<=7; i++) {
if (lines[days[i]])
print lines[days[i]]
else
print "Nobody", days[i]
}
}
' file2 file1 | column -t
Name On-Call Phone
Carol MONDAY 248.344.5576
Bob TUESDAY 313.123.4567
Alice WEDNESDAY 616.556.4458
Dave THURSDAY 734.838.9800
Nobody FRIDAY
Mary SATURDAY 313.449.1390
Ted SUNDAY 248.496.2204