Aqui está outra maneira de fazer isso (versão curta, sem arquivos temporários):
{ 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
Se você precisar dos nomes dos dias em maiúsculas, então:
{ 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
Versão longa:
Digamos que temos dois arquivos, 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
e file2
:
Bob Tuesday
Carol Monday
Jimmy Wednesday
Ted Sunday
Alice Wednesday
Dave Thursday
Harry Monday
Mary Saturday
Lou Sunday
Criamos file3
com o seguinte conteúdo:
1 Monday MONDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
4 Thursday THURSDAY
5 Friday FRIDAY
6 Saturday SATURDAY
7 Sunday SUNDAY
e, em seguida, execute:
{ 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
ou, em uma linha:
{ 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
Saída:
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
Como funciona:
join <(sort file2) <(sort file1) | sort -k2
- os dois primeiros arquivos são unidos com base no segundo campo, então a saída é classificada pela segunda coluna:
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
este é canalizado para join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) -
para associá-lo com file3
com base no segundo campo; -a1
adiciona linhas não correspondentes do arquivo3 à saída e -e "Nobody"
substitui os campos de saída ausentes por "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
o resultado é canalizado novamente para sort -k1n | cut -d' ' -f 2-
para numericamente classificar a saída no 1º campo e depois remover o 1º campo:
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
desde que este foi agrupado {...}
com printf %s\n "Name On-Call Phone"
que imprime o cabeçalho, toda a saída é então canalizada para column -t
para purificá-lo.
Você pode pular um sort
se o arquivo3 já estiver classificado na segunda coluna (por exemplo, desta vez com um arquivo simples de duas colunas3):
5 Friday
1 Monday
6 Saturday
7 Sunday
4 Thursday
2 Tuesday
3 Wednesday
e também atribuir um número de telefone a "Nobody"
, por exemplo 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
saída:
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