【问题标题】:awk select line with variable, cannot open no such fileawk 选择带有变量的行,无法打开没有这样的文件
【发布时间】:2020-09-07 13:57:00
【问题描述】:

我正在为一个基本的 awk 命令而苦苦挣扎。

文件 1:

AB253828.1
AB253829.1
AB253830.1
AB253831.1

文件 2:

accession   accession.version   taxid   gi
A00001  A00001.1    10641   58418
A00002  A00002.1    9913    2
A00003  A00003.1    9913    3
A00004  A00004.1    32630   57971
A00005  A00005.1    32630   57972
A00006  A00006.1    32630   57973
A00008  A00008.1    32630   57974
A00009  A00009.1    32630   57975
A00010  A00010.1    32630   57976

两个文件都有 >1 000 000 行

如果第 2 列对应于文件 1 的模式,我想打印文件 2 的第 2 列和第 3 列 我尝试了很多可能性,但都没有奏效......

for ACC in $(cat file1.txt)
do
    #ACC1=$(echo "\"$ACC\"")
    awk -v OFS='\t'-v z="$ACC" '{ if($2 == z) { print $2,$3 } }' file2.txt
done

我明白了

awk: 无法打开 { if($2 == z) { print $2,$3 } } file2.txt(没有这样的文件或目录)

我检查了,file2 在那里。我想,我的问题是变量 z 但我找不到解决方案。

【问题讨论】:

  • 欢迎来到 SO 并特别感谢您在问题中表现出的努力,您能否在您的问题中发布预期的示例输出并让我们知道,这将使我们更清楚地了解问题。
  • 我在一个 100000 行的测试文件上测试了你的解决方案,10 分钟后我停止了它。下面@tripleee 的解决方案在大约 1.5 秒内完成..... ????

标签: awk


【解决方案1】:

直接的问题是您在第二个-v 选项之前缺少一个空格。 (仔细观察:您将 OFS 设置为 \t-v,然后 Awk 认为 z="$ACC" 是您的实际 Awk 脚本,并寻找 - 并抱怨缺少 - 一个名为 ...您的 Awk 脚本内容的文件。)但是真的,你想更彻底地大修。

awk -v OFS='\t' 'NR==FNR { z[$1]++; next }
    $2 in z { print $2,$3 }' file1.txt file2.txt

这使用一个常见的 Awk 习惯用法将第一个文件读入内存,然后从第二个文件中打印出第二个字段作为第一个文件中的条目存在的记录。这应该快几个数量级,当然也可以轻松修复reading lines with for 反模式。

如果第一个文件太大而无法立即放入内存,则可以将其划分为较小的部分(例如每个 500,000 行?)并分别在每个文件上运行。应该很容易看出 Awk 何时消耗了如此多的内存以致您的系统开始抖动;至少在最初的几次运行中,密切关注top 或一些类似的监控工具,如果它行为不端,则终止该进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2016-02-07
    • 2015-07-06
    • 2020-02-13
    • 1970-01-01
    相关资源
    最近更新 更多