【问题标题】:Redirecting stdout to a file in awk将标准输出重定向到 awk 中的文件
【发布时间】:2015-01-25 14:13:03
【问题描述】:

我正在尝试编写一个 awk 命令来从一个文件中取出某些字段并将它们写入一个新文件。我能够分隔字段(逗号分隔)并将其打印到标准输出,但我不知道如何以正确的格式将其放入新文件中。这是我当前的命令:

$ awk '{FS =","};{print $3}' test.log > test1.log

这会将每行的第三个字段放入新文件中,但在新文件的开头插入 2 个空白行,然后在每个字段之间插入一个空白行。我也想保留逗号分隔符,但无法弄清楚以太。我对 bash 和 awk 还很陌生,因此不胜感激!

这是我的示例数据的一部分:

10.60.3.109, anonymous, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3007]USER, anonymous, -,
10.60.3.109, -, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 530, 1326, [3007]PASS, IEUser@, -,
10.60.3.109, anonymous, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3008]USER, anonymous, -,
10.60.3.109, -, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 530, 1326, [3008]PASS, IEUser@, -,
10.60.3.109, anonymous, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3009]USER, anonymous, -,
10.60.3.109, -, 12/1/2003, 6:56:20, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 530, 1326, [3009]PASS, IEUser@, -,
10.60.3.109, sally, 12/1/2003, 6:56:26, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3010]USER, sally, -,
10.60.3.109, -, 12/1/2003, 6:56:26, MSFTPSVC1, CSS, ipaddr, 16, 0, 0, 530, 1326, [3010]PASS, -, -,
10.60.3.109, sally, 12/1/2003, 6:56:31, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3011]USER, sally, -,
10.60.3.109, -, 12/1/2003, 6:56:31, MSFTPSVC1, CSS, ipaddr, 31, 0, 0, 530, 1326, [3011]PASS, -, -,
10.60.3.109, sally, 12/1/2003, 6:56:36, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3012]USER, sally, -,
10.60.3.109, -, 12/1/2003, 6:56:36, MSFTPSVC1, CSS, ipaddr, 15, 0, 0, 530, 1326, [3012]PASS, -, -,
10.60.3.109, sally, 12/1/2003, 6:56:40, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3013]USER, sally, -,
10.60.3.109, sally, 12/1/2003, 6:56:40, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 230, 0, [3013]PASS, -, -,
10.60.3.109, sally, 12/1/2003, 6:56:40, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3014]USER, sally, -,
10.60.3.109, sally, 12/1/2003, 6:56:40, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 230, 0, [3014]PASS, -, -,
10.60.3.109, sally, 12/1/2003, 6:56:47, MSFTPSVC1, CSS, ipaddr, 0, 0, 0, 331, 0, [3015]USER, sally, -,

【问题讨论】:

  • 如果你只抓取一列,, 分隔符有什么用?您可以发布一些示例输入数据和您的预期输出吗?
  • 最后我复制了几个字段。在原始文件中,每个字段都用逗号分隔,没有空格。
  • awk 'BEGIN {FS=OFS=","}{ print $1, $2, $4 }' test.log > test1.log 将允许您在决定提取多列时保留, 分隔符。

标签: bash awk gawk


【解决方案1】:
awk '{FS =","};{print $3}' test.log > test1.log

第一个动作是{FS = ","},它正在为每一行执行。它可能应该以BEGIN 开头。因为当前没有设置字段分隔符,直到第一行已经被读取和拆分后,第一行很可能被读取为单个字段,因此$3 为空,导致空白行。

第二个动作是;,它打印整行似乎没有做任何事情。您通常不会使用这样的分号。它通常只出现在动作的大括号内。

第三个动作是{print $3},它打印第三个字段(当有第三个字段要打印时)。

我还不确定我是否理解输出开头的双空行,除非你的输入开头有一个空行。我也不是使用 Mac OS X 10.10.1 Yosemite 中的 BSD awk 复制交替的空白行,但也使用 GNU awk 3.1.7。

你可能想要:

awk 'BEGIN {FS = ","} {print $3}' test.log > test1.log

或(在我看来更可取):

awk -F"," '{print $3}' test.log > test1.log

逗号周围的引号是可选的(因为逗号不是 shell 元字符)。但是,如果您稍后要选择多个字段,您可能希望按照jaypal singhcomment 中的建议进行操作,并使用:

awk 'BEGIN {OFS = FS = ","} {print $3, $5, $9}' test.log > test1.log

对于您想要打印的字段的任何排列。

【讨论】:

  • @Rostro:您的数据是否来自 DOS (Windows) 并具有 CRLF 行尾?或者您的数据是否有交替的数据行和空白行?在这里抓着稻草。使用 DOS 格式文件进行快速试验不会出现问题。
  • @Rostro:就像我说的,我正抓着稻草。正如我在评论更新中指出的那样,无论如何,CRLF 似乎对我没有任何影响。 (我的测试数据文件有行a,b,c,d 然后1,2,3,4 然后a,b,c,d 再次,以Unix 或DOS 行结尾。)我可以在开头解释一个空行;我无法解释交替场 3 行和空白行。例如,您能显示示例数据的前 10 行吗?
  • 好的。您是在类 Unix 系统上还是在 Windows 系统上?您使用的是哪个版本的awk?我仍然怀疑分号是空行的原因。如果您在脚本中省略分号,它们会出现吗?
  • 有趣。在我的 Ubuntu 14.04 上,awk 是指向 /etc/alternatives/awk 的链接,而 /etc/alternatives/awk 又链接到 /usr/bin/mawk,后者拒绝识别版本。问题中显示的数据中有大量空格,因此当我尝试您的脚本时,它会在第一行打印 $3 的值(对于显示的片段,它是 12/1/2003,)。我什至不再确定我可以解释你的空行输出——除非你没有显示真正的日志文件。当我在 Ubuntu 14.04 LTS 上安装 gawk 时,我得到了 gawk 4.0.1。
猜你喜欢
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
相关资源
最近更新 更多