【问题标题】:Save to a path with awk使用 awk 保存到路径
【发布时间】:2014-05-13 01:38:42
【问题描述】:

我有一个包含很多行的文件,其中包含一个哈希和一些格式的文本

DEADBEEF Some text
CAFEBABE More text
DEADBEEF Blah, blah

我想将它逐行拆分为由哈希命名的文件。我设法用 awk 做到了:

awk '{ print substr($0, 10, 1000) >> substr($0, 1, 8); close(substr($0, 1, 8))}'

这给了我一个名为 DEADBEEF 的文件,其中包含内容

Some text
Blah, blah

和另一个包含内容的文件 CAFEBABE

More text

问题是,我有很多文件,文件系统变慢,一个文件夹中有很多文件,所以我想将文件拆分到一些文件夹中,例如 DE/DEADBEEF 和 CA/CAFEBABE。

我该怎么做? 可以吗?

【问题讨论】:

  • 您可以sort 您的输入文件,并创建一个索引,其中包含指向应该代表特定文件的节的开始位置的指针。在编写索引时,您还可以重写已排序的输入,删除哈希数据。如果您需要同一部分中的行之间的顺序与初始文件中的相同,只需使用稳定的排序算法即可。

标签: bash awk


【解决方案1】:

尝试以下方法:

awk '{ 
    d=substr($0, 1, 2);                           # Determine output dir. name
    f=d "/" substr($0, 1, 8);                     # Determine output file path.
    if (!dirs[d]++) system("mkdir -p \"" d "\""); # Make sure output dir. exists.
    print substr($0, 10, 1000) >> f;              # Output line.
    close(f);                                     # Close output file.
  }
  ' file

注意事项

  • 由于输出文件被盲目地追加到 (>>),因此在运行命令之前,您应该确保输出文件夹为空。 (如果输出文件夹本身已经存在,那很好。)
  • (!dirs[d]++) 条件确保仅对尚未创建的目录调用 system()(通过使用按需创建的名为 dirs 的关联数组) - 正如 OP @geon 通过基准测试确定的那样,这优化大大提高了性能。

【讨论】:

  • 作为一个侵入性较小的修复程序,您可以在运行原始 Awk 脚本的稍微复杂一点的版本之前只 cut -c1-2 inputfile | sort -u | xargs mkdir -p。我想从 awk 脚本中删除 system 调用会使其更快,但我没有执行任何测量。
  • 我相信你可以只使用substr($0,10) 并失去人为的 1000 限制。
  • @tripleee:好点子,但我保留了来自 OP 的 substr()call,因为我不知道这是否是故意的。
  • @tripleee:用cut ...重新预处理:有趣的想法;如果您可以比较性能,请告诉我们。我刚刚包含了一个优化,其中 system() 仅针对尚未遇到的目录名称调用 - 这应该会有所帮助。
  • @mklement0:我在优化和不优化的情况下对您的代码进行了基准测试。对于未优化的代码,它非常慢。我没有让它完成,但我将一个文件夹计时到 00:01:03。所有 256 个文件夹的投影时间为 04:28:48。通过优化,它在 00:06:30 完成 - 41 倍。太好了!
【解决方案2】:

纯外壳

while read -r filename content
do
  dir=${filename:0:2}
  mkdir -p "${dir}"
  echo "$content" >> "${dir}/${filename}"
done < file

【讨论】:

  • +1,但也许 (a) 将 变量 file 重命名为 filename 以便与输入文件名 literal 区分开来同名,并且 (b) 为了安全起见,我建议双引号 ${d}${d}/${file}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2016-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
相关资源
最近更新 更多