bash - 如何使用 GNU 并行处理 'read word1 word2' 的等价物
问题描述
我有一个管道,它给了我两行带引号的空格分隔的字符串。使用 echo 给你一个管道内容的例子:
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""
"filename1" "some text 1"
"filename2" "some text 2"
第一个字符串是文件名,第二个是我要附加到该文件的文本。使用“read”获取 $filename 和 $text 的句柄很容易:
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""|
while read filename text; do echo $text $filename; done
"some text 1" "filename1"
"some text 2" "filename2"
但是“parallel”并不想把线上的两个字符串当作两个参数。似乎将他们视为一体。
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""|
parallel echo {2} {1}
"filename1" "some text 1"
"filename2" "some text 2"
所以只要有 {1} 就可以得到相同的结果
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""|
parallel echo {1}
"filename1" "some text 1"
"filename2" "some text 2"
添加--colsep ' '
使它打破每个空间的字符串
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""|
parallel --colsep ' ' echo {2} {1}
"some "filename1"
"some "filename2"
我只是在其文档https://www.gnu.org/software/parallel/man.html中找不到有关如何通过管道并行处理此案例的解释
添加一个--delimiter ' '
选项给出了这个
echo -e "\"filename1\" \"some text 1\"\n\"filename2\" \"some text 2\""|
parallel --delimiter ' ' echo {2} {1}
"filename1"
"some
text
1"
"filename2"
"some
text
2"
这是我找到的最接近的
seq 10 | parallel -N2 echo seq:\$PARALLEL_SEQ arg1:{1} arg2:{2}
seq:1 arg1:1 arg2:2
seq:2 arg1:3 arg2:4
seq:3 arg1:5 arg2:6
seq:4 arg1:7 arg2:8
seq:5 arg1:9 arg2:10
但它并没有真正反映我的数据,因为seq 10
每个字符串后面都有一个新行,而且我有两个字符串。
1
2
3
4
5
6
7
8
9
10
我目前的解决方法是将管道更改为使用逗号而不是空格来分隔一行中的引用字符串:
echo -e "\"filename1\",\"some text 1\"\n\"filename2\",\"some text 2\""|
parallel --colsep ',' echo {2} {1}
"some text 1" "filename1"
"some text 2" "filename2"
但是如何并行处理呢?
解决方案
如果您对去除引号感到满意,那么--csv
与之配对的选项--colsep
将拆分到您想要的位置(并且仍然正确保留所有空格)
echo -e "\"filename1\" \"some text 1\"\n\"filename2 withspaces\" \"some text 2\""|
parallel --csv --colsep=' ' echo arg1:{1} arg2:{2}
输出:
arg1:filename1 arg2:some text 1
arg1:filename2 withspaces arg2:some text 2
注意--csv
需要安装 perlText::CSV
模块 ( sudo cpan Text::CSV
)
如果你想保留引号,混合-q
和一些额外的引号会将它们添加回来:
echo -e "\"filename1\" \"some text 1\"\n\"filename2 withspaces\" \"some text 2\""|
parallel -q --csv --colsep=' ' echo 'arg1:"{1}" arg2:"{2}"'
输出:
arg1:"filename1" arg2:"some text 1"
arg1:"filename2 withspaces" arg2:"some text 2"
--csv
仅在最新版本的并行中(自 2018-04-22 起)。如果您年龄较大parallel
,最好先通过预处理步骤将输入转换为并行可以处理的格式。我能看到的唯一方法是对 shell 引用和内部parallel
处理进行真正的 hacky 开发:parallel
echo -e "\"filename1\" \"some text 1\"\n\"filename2 with spaces\" \"some text 2\""|
parallel sh -c "'echo arg1:\"\$1\" arg2:\"\$2\"'" echo '{= $Global::noquote = 1 =}'
输出:
arg1:filename1 arg2:some text 1
arg1:filename2 with spaces arg2:some text 2
这是如何工作的,我将作为练习留下......运行parallel --shellquote
将显示它在引擎盖下构建的命令。
推荐阅读
- apache-spark - 如何将火花rdd的副本存储到另一个rdd中
- python - 将csv中的行插入mysql数据库
- maven - 如何在 Maven 构建期间从属性文件创建 kubernetes configmap?
- java - 使用 Spring 动态创建同一 bean 的多个实例
- python - 给出不同最小距离的汉明码神经编码器
- java - 膨胀类 ja.burhanrashid52.photoeditor.PhotoEditorView 时出错
- arangodb - 如何在 ArangoDB 中返回文档之前在文档中添加/删除属性?
- angular - rxJS 的 debounceTime 在本地工作时工作,但在构建后它没有按预期工作
- javascript - 如何检查字符串是否与 Mongoose 的数组元素匹配
- python - 为 Ximea 相机设置下采样