【问题标题】:Issues with the AWK functionAWK 函数的问题
【发布时间】:2013-11-26 17:29:32
【问题描述】:

Awk 可以处理的数据量是否有限制?

for i in "052" "064" "060" "070" "074" "076" "178"
do
        awk -v f="${i}" -F, 'match ($1,f) { print $2","$3 }' uls.csv > ul$i.csv
        awk -v f="${i}" -F, 'match ($1,f) { print $2","$3 }' dls.csv > dl$i.csv
        awk -v n="${i}" -F, 'match ($1,n) { print $2","$3 }' dlsur.csv >> dlu$i.csv
        awk -v k="${i}" -F, 'match ($1,k) { print $2","$3 }' dailyd.csv >> dla$i.csv
        awk -v m="${i}" -F, 'match ($1,m) { print $2","$3 }' dailyu.csv >> ula$i.csv

done

当我运行那段代码时,它基本上从 csv 文件中提取数据并创建新文件。 那段代码完美运行。 但是当我添加一个额外的文件(在 for 循环中)时,例如“180”,它将创建该文件,但也会包含来自其他文件的几行数据。我检查了很多次代码。我什至在原始数据进入这个循环之前检查了它,它都是正确的。这似乎是 awk 中的一个小故障。 我是否需要应用等待功能才能赶上?

【问题讨论】:

  • 你的正则表达式很笼统;你确定它没有匹配比预期更多的行吗?
  • 不是。每一行都有一个唯一的 id,这也是文件名的一部分,所以 052 和 064 都是 id。
  • 但是字符串会出现在该行的其他位置吗? $0 是整行,而不是第一个字段。也许你想要match($1, f)
  • 当我在循环后打开文件时,它显示新文件的id,但新id和另一个id的数据。
  • 文件是否最初来自 Windows 的 PC?当我将文件从 windows 导入到 linux 上进行 awking 时,我通常需要 vi 和 :set ff=unix:set nobomb 让它们按预期运行。

标签: linux bash csv awk


【解决方案1】:

类似

for file in uls dls dlsur dailyd dailyu; do
    awk -F, -vOFS=, -vfile=$i '$1 ~ /052|064|060|070|074|076|178/ {print $2,$3 >> file$1.csv}' $file.csv
done

如果它可以满足您的需求,可能会更好。更少的 awk 调用和文件循环。 (输出文件名略有不同。这是可以修复的,但脚本比我认为的要复杂一些。)

【讨论】:

    【解决方案2】:

    没有。你所说的你认为正在发生的事情不可能发生 - awk 不会从未指定的文件中随机提取数据并将其放入它的输出流中。

    请注意,在您的第 3 行和后续行中,您使用 '>>' 而不是 '>' 进行输出重定向 - 您是否考虑到了这一点?

    如果您更新您的问题(即不要在评论中尝试这样做!)告诉我们您要对一些代表性示例输入和预期输出做什么(应该是 2 个输入文件,而不是 5 个,应该是足以解释您的问题),我们可以帮助您编写正确的脚本来做到这一点。

    【讨论】:

    • 它现在有效,只是我无法弄清楚它为什么有效。
    • 如果您不知道是什么导致了问题,那么当您在文件中有一些不同的输入时,您怎么知道它不会在将来重新出现?显然,这是您解析输入的方式导致了您的问题,因为通过更改您在输入文件中的查看位置,您更改了输出,但这当然并不意味着您已经解决了问题,只是问题已经消失了现在给定您当前的特定输入集。它会在您最不希望出现的时候再次出现,因为您对如何解决问题存在根本性的误解。
    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2019-12-14
    • 1970-01-01
    • 2012-09-03
    • 2011-04-29
    • 2013-02-03
    • 1970-01-01
    • 2011-06-13
    相关资源
    最近更新 更多