【问题标题】:Combine text from two files, output to another [duplicate]合并两个文件中的文本,输出到另一个[重复]
【发布时间】:2013-12-09 18:13:54
【问题描述】:

我遇到了一些问题,我整天都在寻找。这是我的第一个 Unix 课程,不要太苛刻。

所以这听起来很简单,但我无法理解

我有两个文本文件

文件1

David 734.838.9801
Roberto‭ ‬313.123.4567
Sally‭ ‬248.344.5576
Mary‭ ‬313.449.1390
Ted‭ ‬248.496.2207
Alice‭ ‬616.556.4458
Frank‭ ‬634.296.1259

文件2

Roberto Tuesday‭ ‬2
Sally Monday‭ ‬8
Ted Sunday‭ ‬16
Alice Wednesday‭ ‬23
David Thursday‭ ‬10
Mary Saturday‭ ‬14
Frank Friday‭ ‬15

我正在尝试使用循环结构编写脚本,该结构将结合两个文件并将下面的输出作为单独的文件输出

输出:

Name       On-Call    Phone        Start Time

Sally      Monday     248.344.5576  8am

Roberto    Tuesday    313.123.4567  2am

Alice‭      Wednesday‭  616.556.4458‭  11pm

David‭      Thursday‭   734.838.9801‭  10am

Frank‭      Friday‭     634.296.1259‭   3pm

Mary‭       Saturday‭   313.449.1390‭   2pm

Ted‭ ‬       Sunday‭     248.496.2207‭   4pm

这是我尝试过的(我知道它很可怕)

echo " Name     On-Call          Phone      Start Time"
file="/home/xubuntu/date.txt"
file1="/home/xubuntu/name.txt"
while read name2 phone
do
while read name day time
do
echo "$name     $day   $phone           $time"
done<"$file"
done<"$file1"

任何帮助将不胜感激

【问题讨论】:

  • 有一种有效的方法...使用粘贴
  • @Chandranshu 宣传您自己的答案?给这个人一些时间来尝试这两个答案。此外,几个小时后可能会有更好的答案:)
  • 感谢您的帮助,由于某种原因,我收到错误 awk: 1: unexpected character '&'
  • 对不起,我是这个东西的超级菜鸟

标签: bash shell unix loops while-loop


【解决方案1】:

首先,使用sort 对文件进行排序,然后使用以下命令:

paste file1 file2 | awk '{print $1,$4,$2,$5}'

这将使您非常接近。之后,您必须弄清楚如何将时间从 24 小时格式转换为 12 小时格式。

如果你想避免单独使用sort,你可以像这样增加一点复杂性:

paste <(sort file1) <(sort file2) | awk '{print $1,$4,$2,$5}'

最后,如果您还没有弄清楚如何以 12 小时格式打印时间,这里是您的完整命令:

paste <(sort file1) <(sort file2) | awk '{"date --date=\"" $5 ":00:00\" +%I%P" |& getline $5; print $1 " " $4 " " $2 " " $5 }'

您可以使用制表符 (\t) 代替空格作为连接符,以获得格式良好的输出。

【讨论】:

  • paste 只会合并两个文件中的列,而不考虑任何常见的列。但是这里需要根据common column来加入..
  • 嗨,感谢您的回复,它确实有效,但是有什么方法可以产生相同的结果,但具有循环结构?
  • @Mari - 这就是涉及到排序的原因。它确保每个文件上的对应行具有相同的名称。
  • @bypass_override - 是的,您始终可以遍历两个结果集,但假设每个文件中有 n 行,该解决方案将花费您 O(n^2) 时间。提出的解决方案需要 O(n log n) 时间。
  • 是的 @Chandranshu 知道了 :) 感谢您的澄清。我刚刚发布了带有 join 命令的替代方法。如果有任何问题,请告诉我。不过我测试过了..
【解决方案2】:

在这种情况下join command 也可以工作,

join -1 1 -2 1 <(sort file1) <(sort file2)

说明

-1 -> file1
1  -> first field of file1 (common field)
-2 -> file2
1 -> first field of file2 (common field)


**cat file1**

David 734.838.9801
Roberto 313.123.4567
Sally 248.344.5576
Mary 313.449.1390
Ted 248.496.2207
Alice 616.556.4458
Frank 634.296.1259

**cat file2**

Roberto Tuesday 2
Sally Monday 8
Ted Sunday 16
Alice Wednesday 23
David Thursday 10
Mary Saturday 14
Frank Friday 15

输出

Alice 616.556.4458 Wednesday 23
David 734.838.9801 Thursday 10
Frank 634.296.1259 Friday 15
Mary 313.449.1390 Saturday 14
Roberto 313.123.4567 Tuesday 2
Sally 248.344.5576 Monday 8
Ted 248.496.2207 Sunday 16

【讨论】:

  • 有一个小问题:join 期望输入文件被排序。以下是手册页中的相关部分: 重要提示:FILE1 和 FILE2 必须在连接字段上排序。例如,如果 join' has no options, or use join -t '' ' 如果 `sort' 没有选项,则使用 `sort -k 1b,1 '。对 OP 来说可能是也可能不是问题的另一个问题是您无法指定输出中列的顺序。
  • 如您的输出所示,join 忽略了通过前向迭代找不到匹配项的行。
  • 是的,对@Chandranshu。 .所以它需要对文件进行排序..让我编辑它。感谢您的意见..
  • 你可以简单地使用这个命令:join -1 1 -2 1 &lt;(sort file1) &lt;(sort file2)。我宁愿自己使用join,除非涉及到时间的变化。
  • 是的,完全正确..因为它是基于公共列的连接,我更喜欢使用连接命令..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
相关资源
最近更新 更多