【问题标题】:awk overwriting files in a loopawk 循环覆盖文件
【发布时间】:2015-08-20 13:14:36
【问题描述】:

我正在尝试浏览一组文件。在 2 年内每个月有 4-5 个文件,其中包含 1000 多个站点。我正在尝试将它们分开,以便每个 station_no (station_no = $1) 有一个文件。

我认为这很容易,并且很简单;

awk -F, '{ print > $1".txt" }' *.csv

我已经用一个文件进行了测试,它工作正常。但是,当我运行它时,它会创建 .txt 文件,但文件中没有任何内容。

我现在试着把它放在一个循环中,看看它是否有效;

#!/bin/bash
#program to extract stations from orig files

for file in $(ls *.csv)

do 
    awk -F, '{print > $1".txt" }' $file

done

它在循环文件等时工作,但它会在移动到下个月时不断覆盖。

如何阻止它覆盖并仅添加到具有该名称的 .txt 的末尾?

【问题讨论】:

  • 只需使用>> 追加而不是>,这会截断之前的内容。
  • 天哪,我就知道会这么简单!非常感谢!我花了最后半个小时在谷歌上搜索为什么它不起作用:D
  • 这是一个错字。谢谢:)
  • 啊,谢谢,我确实尝试过这样做,但它说我可以“在 4 分钟内接受答案”,所以会等待然后打勾:)
  • for file in *.csv 会比for file in $(ls *.csv) 好很多...解析ls 的输出通常被认为是相当不利的...

标签: bash awk overwrite


【解决方案1】:

您说的是print > file,它会在每次新呼叫时截断。请改用>>,以便它附加到之前的内容。

此外,无需遍历所有文件,然后为每个文件调用awk。相反,将文件集提供给awk,如下所示:

awk -F, '{print >> ($1".txt")}' *.csv

但是,请注意,我们需要谈谈awk 如何保持打开文件以供写入。如果你说awk '{print > "hello.txt"}' file,awk 将保持hello.txt 文件打开,直到它完成处理。在您当前的方法中,awk 在每个文件上都停止;但是,在我目前建议的方法中,文件在处理完最后一个文件之前是打开的。因此,在这种情况下,单个 > 就足够了:

awk -F, '{print > $1".txt"}' *.csv

( file ) 的详细信息,请参阅 Ed Morton 的 cmets,我无法比他更好地解释它:)

【讨论】:

  • 但是,您确实需要parens print >> ($1".txt") 以实现可移植性,并且由于您已经摆脱了循环(对吗?)您不再需要>>,您可以返回>,即@ 987654336@。如果您不使用 gawk,您可能还会发现偶尔需要关闭打开的文件。
  • @EdMorton 所以如果我理解正确的话:在 OP 的方法中,当awk 完成处理文件时文件会关闭(心理上:到达END 时)。所以在我目前的方法中没有必要,因为所有文件指针都在最后被释放。唯一的问题是万一此时打开了这么多文件,对吧?
  • @EdMorton 很棒,一直向你学习。已更新,当然可以随时修复任何错误!
猜你喜欢
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 2022-10-15
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多