【问题标题】:Bash oneliner with AWK runs in terminal but not in script带有 AWK 的 Bash oneliner 在终端中运行,但不在脚本中
【发布时间】:2013-11-27 16:42:07
【问题描述】:

我有一个包含以下数据类型的文件:

4-11-11 12:59:01,C,26,668
4-11-11 12:59:31,C,26,668
4-11-11 13:00:01,C,26,668
4-11-11 13:00:31,C,26,668
4-11-11 13:01:01,C,26,668
4-11-11 13:01:31,C,26,668

我想要以下输出:

12:59:01 26.668
12:59:31 26.668
13:00:01 26.668
13:00:31 26.668
13:01:01 26.668
13:01:31 26.668

这在带有以下行的终端中工作得很好,但在 bash 脚本中却不行,它只是给了我一个空文件。在我添加了 awk 部分后,问题就开始了。

cut -d ' ' -f2 $file | cut -d ',' -f-1,3- | awk -f tmp.csv -F"," '{print $1 " " $2 "." $3}' | sed 's/"//'  > tmp.csv
cp tmp.csv > $file

谁能解释为什么这在脚本中不起作用?

谢谢!

【问题讨论】:

  • 您确定要使用 tmp.csv 作为 awk 的脚本文件和命令的输出吗?因为这是您要求 awk/sed 做的事情。

标签: bash awk cut


【解决方案1】:

我猜你在脚本中的环境是罪魁祸首,但整个事情可以只使用read

while IFS=' ,' read a b c d e
do
  echo "$b $d.$e"
done < inputfile

也许这可以在不同的层面上解决问题;-)

【讨论】:

    【解决方案2】:

    有了这个awk 会更容易:

    $ awk -F'[ ,]' '{print $2, $4"."$5}' file
    12:59:01 26.668
    12:59:31 26.668
    13:00:01 26.668
    13:00:31 26.668
    13:01:01 26.668
    13:01:31 26.668
    
    • -F'[ ,]' 设置两个可能的分隔符:空格和逗号。
    • print $2, $4"."$5 根据这些分隔符打印第 2、第 4 和第 5 个字段。

    关于你的脚本为什么不起作用,只是因为你不必要地添加了-f tmp.csv

    $ cut -d ' ' -f2 a | cut -d ',' -f-1,3- | awk -F"," '{print $1 " " $2 "." $3}' | sed 's/"//'
    12:59:01 26.668
    12:59:31 26.668
    13:00:01 26.668
    13:00:31 26.668
    13:01:01 26.668
    13:01:31 26.668
    

    您还使用-f tmp.csv,然后使用&gt; tmp.csv,这是没有意义的。注意一个文件不能同时用作标准输入和标准输出。

    【讨论】:

    • 这很好用,谢谢!出于好奇(为了避免将来出现问题),我仍然想知道为什么我的解决方案在脚本中不起作用,知道吗?
    • @Xizam 刚刚相应更新。稍作改动(删除-f file)对我有用。查看更新。
    • -f tmp.csv 实际上不在我试图在脚本中运行的代码中,那是我草率地复制。实际的问题在于我愚蠢到使用“for file in *.csv”并将输出保存到 tmp.csv。我还没有用 tmp.csv 覆盖我的原始文件,所以如果脚本不起作用,我就不必继续复制它们。所以 tmp.csv 文件在最后一步被覆盖,给了我一个空文件。感谢您的帮助。
    • 很高兴只是这样,这是一个常见的错误,所以不要怪自己:)
    • 第一种形式是一个或分隔的 RE 列表,第二种是一组字符。您实际上并不想要/不需要使用或分隔的 RE 列表,您只是想使用一组字符,因此只需指定使用适当的语言结构即可。从功能上讲,它们与这 2 个特定字符的行为相同,但是如果需要句点或问号或任何其他 RE 元字符作为附加字段分隔符,这将很重要。如果您在第一种形式上进行构建,则第一种形式也开始看起来很傻,例如"a|b|c|d" vs "[abcd]",这是另一个表明它不是正确的方法。
    【解决方案3】:

    您不是在复制临时文件;您只是在擦除原始文件。我不确定您为什么没有收到错误(应该是,因为 cp 需要两个参数)。

    而不是

    cp tmp.csh > $file
    

    使用

    cp tmp.csv "$file"
    

    【讨论】:

    • 对。甚至没有注意到这一点。但我觉得你在这里发现的错误只是在问题中,而不是在 OP 实际使用的脚本中(复制/粘贴错误)。
    猜你喜欢
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2013-06-27
    相关资源
    最近更新 更多