bil*_*arr 4 shell text-processing date sort
我有两个文件。
文件 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
Run Code Online (Sandbox Code Playgroud)
文件2:
Bob Tuesday
Carol Monday
Ted Sunday
Alice Wednesday
Dave Thursday
Mary Saturday
Run Code Online (Sandbox Code Playgroud)
我合并了这两个文件。
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
Run Code Online (Sandbox Code Playgroud)
但我无法让工作日井井有条。我该怎么做?
这是另一种方法(简短版本,没有临时文件):
{ 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
Run Code Online (Sandbox Code Playgroud)
如果您绝对需要大写的日期名称,那么:
{ 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
Run Code Online (Sandbox Code Playgroud)
长版本:
假设我们有两个文件,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
Run Code Online (Sandbox Code Playgroud)
和file2
:
Bob Tuesday
Carol Monday
Jimmy Wednesday
Ted Sunday
Alice Wednesday
Dave Thursday
Harry Monday
Mary Saturday
Lou Sunday
Run Code Online (Sandbox Code Playgroud)
我们file3
使用以下内容创建:
1 Monday MONDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
4 Thursday THURSDAY
5 Friday FRIDAY
6 Saturday SATURDAY
7 Sunday SUNDAY
Run Code Online (Sandbox Code Playgroud)
然后运行:
{ 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
Run Code Online (Sandbox Code Playgroud)
或者,在一行中:
{ 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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
工作原理:
join <(sort file2) <(sort file1) | sort -k2
- 前两个文件基于第二个字段连接,然后输出按第二列排序:
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
Run Code Online (Sandbox Code Playgroud)
这通过管道输送到join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) -
与连接它file3
基于第二字段; -a1
将 file3 中不匹配的行添加到输出中,并将-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
Run Code Online (Sandbox Code Playgroud)
结果再次通过管道传输到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
Run Code Online (Sandbox Code Playgroud)
由于这是{...}
与printf %s\\n "Name On-Call Phone"
打印标题的分组,因此整个输出然后通过管道传输以对其column -t
进行美化。
sort
如果 file3 已经在第二列上排序(例如这次使用简单的两列 file3),您可以跳过一个:
5 Friday
1 Monday
6 Saturday
7 Sunday
4 Thursday
2 Tuesday
3 Wednesday
Run Code Online (Sandbox Code Playgroud)
并分配一个电话号码,"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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)