是否可以通过 GNU 并行并行 awk 写入多个文件?

2024-02-29

我正在运行一个 awk 脚本,我想通过 GNU 并行对其进行并行化。

该脚本根据每一行上的值将一个输入文件多路分解为多个输出文件。代码如下:

#!/usr/bin/awk -f

BEGIN{ FS=OFS="\t" }
{
    # bc is the field that defines to which file the line
    # will be written
    bc = $1
    # append line to such file
    print >> (bc".txt")
}

我想通过以下方式使用 GNU 并行对其进行并行化:

parallel --line-buffer --block 1G --pipe 'awk script.awk'

但是,我担心两个 awk 进程同时写入同一个文件时可能出现的竞争情况。是否可能,如果可能,如何在不影响并行性的情况下避免这种情况?

注意。包括我--line-buffer选项,尽管我不确定它是否也适用于 awk 脚本内的文件重定向。它是否也适用于这种情况或仅适用于每个 awk 进程的标准输出?

Example

# Input file
bc1    line1
bc3    line2
bc1    line3
bc2    line4


# Output file bc1.txt
bc1    line1
bc1    line3

# Output file bc2.txt
bc2    line4

# Output file bc3.txt
bc3    line2

您可以通过对不同目录中的输出进行多路分解来实现:

stuff |
  parallel --block 10M --pipe --round-robin \
    'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk'

或者如果输入是文件,您可以使用--pipepart哪个更快:

parallel --block -1 --pipepart -a bigfile \
  'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk'

那么就没有竞争条件了。通过合并目录完成:

parallel 'cd {}; ls' ::: dir-* | sort -u |
  parallel 'cat */{} > {}'

如果无法接受合并(也许您没有磁盘空间来容纳 2 个数据副本),则可以使用 fifo。但要做到这一点,你需要知道所有的名字.txt- 提前创建文件,并且您需要一个可以并行运行每个名称一个进程的系统(10000 个名称 = 10000 个进程):

# Generate names-of-files.txt somehow
# Make fifos for all names in all slots
parallel 'mkdir -p {2}; mkfifo {2}/{1}' :::: \
  names-of-files.txt <(seq $(parallel --number-of-threads) )
# Run the demultiplexer in the background
parallel --block -1 --pipepart -a bigfile \
  'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk' &
# Start one process per name
# If you have more than 32000 names, you will need to increase the number
# of processes on your system.
cat names-of-files.txt |
  parallel -j0 --pipe -N250 -I ,, parallel -j0 'parcat */{} > {}'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以通过 GNU 并行并行 awk 写入多个文件? 的相关文章

  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 目录 * 和文件顺序

    我需要将目录中的所有文件连接到一个文件 但具有指定名称的文件必须位于输出的顶部 只是在做cat gt result将按字母顺序连接所有文件 有什么办法告诉猫放置文件vars css或任何其他输出的开头 现在我只是重命名文件需要首先000 f
  • 如何将 bash 脚本的整个输出保存到文件

    我正在尝试将 bash 脚本的整个输出保存到文件中 我目前在代码开头有一个参数 ip 地址 如下所示 bin bash USAGE Usage 0
  • 如何让“grep -zoP”单独显示每个匹配项?

    我有一个此表格的文件 X this is the first match blabla X this is the second match and here we have some fluff 我想提取 X 之后和相同标记之间出现的所有
  • 在 Linux 中禁用历史记录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 要在 Linux 环境中禁用历史记录 我执行了以下命令 export HISTFILESIZE 0 export HISTSIZE 0 u
  • bash 支持字边界正则表达式吗?

    我试图在再次添加该单词之前匹配列表中是否存在该单词 以避免重复 我正在使用 bash 4 2 24 并尝试以下操作 foo bmyword b also foo
  • 如果文件为空,如何跳过文件行

    python 3中的程序 这是我的第一个涉及文件的程序 我需要忽略注释行 以 开头 和空行 然后拆分这些行 以便它们可迭代 但我不断收到 IndexError 消息 指出字符串索引超出范围 并且程序在空行处崩溃 import os path
  • 如何使用 PHP 查找目录中的前 5 个文件?

    如何使用 PHP 列出按字母顺序排序的目录中的前 5 个文件或目录 Using scandir array slice array filter scandir path to dir is file 0 5 The array filte
  • 在bash中,是否有相当于“错误消息”的东西

    在 perl 中 您可以使用错误消息退出die some msg bash 中是否有等效的单个命令 现在 我正在使用命令来实现这一点 echo some msg exit 1 你可以很容易地自己推出 die echo 1 gt 2 exit
  • 如何使用我在 github 中发布的 bash 脚本执行 chsh?

    我有一个要点 我总是用它来在新服务器上安装我需要的软件包 http gist github com 4372049 http gist github com 4372049 我需要做的就是通过 ssh 在新服务器中输入以下内容 bash c
  • 仅当重复行与模式匹配时才删除它们

    这个问题 https stackoverflow com questions 1444406 how can i delete duplicate lines in a file in unix有一个很好的答案说你可以使用awk seen
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 在 Ruby 中创建一个空文件:相当于“touch”?

    创建一个的最佳方式是什么emptyRuby 中的文件 类似于 Unix 命令的东西 touch https en wikipedia org wiki Touch 28Unix 29 touch file txt FileUtils tou
  • grep 两个分隔符之间的子字符串

    我有很多bash使用的脚本perl内的表达式grep为了提取两个分隔符之间的子字符串 例子 echo BeginMiddleEnd grep oP lt Begin End 问题是 当我将这些脚本移植到运行的平台时busybox 融合的 g
  • 迭代 bash 脚本中的变量名称

    我需要在一堆文件上运行一个脚本 这些文件的路径被分配给train1 train2 train20 我想 为什么不使用 bash 脚本使其自动执行呢 所以我做了类似的事情 train1 path to first file train2 pa
  • 如何在数组中存储包含双引号的命令参数?

    我有一个 Bash 脚本 它生成 存储和修改数组中的值 这些值稍后用作命令的参数 对于 MCVE 我想到了任意命令bash c echo 0 0 echo 1 1 这解释了我的问题 我将用两个参数调用我的命令 option1 without
  • jq:将对象数组转换为对象

    我收到了来自curl的回复 格式如下 list value 1 id 12 value 15 id 13 value 4 id 14 给定 id 之间的映射 如下所示 12 newId1 13 newId2 14 newId3 我想做这个
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t

随机推荐