我一直试图使用GNU并行一段时间,但我从来没有能够让它完全运行!
例如,运行(在非空目录中!):
ls | parallel echo # Outputs single new line
ls | parallel echo echo echo # Outputs three new lines.
ls | parallel echo {} # /bin/bash: {}: command not found
ls | parallel echo '{}' # /bin/bash: {}: command not found
ls | parallel 'echo {}' # Outputs: {}
ls | parallel -IMM 'echo MM' # Outputs: MM
Run Code Online (Sandbox Code Playgroud)
它似乎只是将每个参数作为命令执行,这没有任何意义.
我试过bash,zsh,tcsh,csh和sh,但无济于事.
使用GNU parallel:http://www.gnu.org/software/parallel/
我有一个程序,需要两个参数,例如
$ ./prog file1 file2
$ ./prog file2 file3
...
$ ./prog file23456 file23457
Run Code Online (Sandbox Code Playgroud)
我正在使用生成文件名对的脚本,但这会产生问题,因为脚本的结果是单个字符串 - 而不是一对.喜欢:
$ ./prog "file1 file2"
Run Code Online (Sandbox Code Playgroud)
GNU parallel 似乎有一大堆技巧,我想知道是否有一个用于在分隔符周围分割文本:
$ generate_file_pairs | parallel ./prog ?
# where ? is text under consideration, like "file1 file2"
Run Code Online (Sandbox Code Playgroud)
简单的解决方法是在prog中手动拆分args,但我想知道它是否可能GNU parallel.
我有一列的 name.txt 文件,例如
A
B
C
D
E
F
Run Code Online (Sandbox Code Playgroud)
然后我有很多文件,egxtxt, y.txt 和 z.txt
x.txt 有
A 1
C 3
D 2
Run Code Online (Sandbox Code Playgroud)
y.txt 有
A 1
B 4
E 3
Run Code Online (Sandbox Code Playgroud)
z.txt 有
B 2
D 2
F 1
Run Code Online (Sandbox Code Playgroud)
理想的输出是(如果没有映射就填0)
A 1 1 0
B 0 4 2
C 3 0 0
D 2 0 2
E 0 3 0
F 0 0 1
Run Code Online (Sandbox Code Playgroud)
可以用bash制作吗?(也许是 awk?)
非常感谢!!!
第一次编辑 - 我的尝试性工作
由于我对 bash 还很陌生,所以我真的很难用 awk 找出可能的解决方案。我更熟悉R,可以通过
namematrix[namematrix[,1]==xmatrix[,1],]
Run Code Online (Sandbox Code Playgroud)
总而言之,我真的很感谢下面的帮助,帮助我更多地了解awk和join!
第二次编辑 …
我正在尝试学习GNU Parallel,因为我有一个案例,我认为我可以轻松地并行化bash函数.所以在尝试学习的时候,我去了GNU Parallel手册,里面有一个例子 ......但我甚至无法让它工作!以机智:
(232) $ bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
(233) $ cat tpar.bash
#!/bin/bash
echo `which parallel`
doit() {
echo Doing it for $1
sleep 2
echo Done with $1
}
export -f doit
parallel …Run Code Online (Sandbox Code Playgroud) 我正在将一个非常巨大的文件加载到postgresql数据库中.为此,我首先split在文件中使用以获取较小的文件(每个30Gb)然后使用GNU Parallel和将每个较小的文件加载到数据库psql copy.
问题是分割文件大约需要7个小时,然后开始为每个核心加载一个文件.我需要的是一种告诉split每次完成文件写入时将文件名打印到std输出的方法,这样我就可以将Parallel它管道输出,并在split完成编写时开始加载文件.像这样的东西:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
Run Code Online (Sandbox Code Playgroud)
我已阅读split手册页,但找不到任何内容.有没有办法用这个split或任何其他工具做到这一点?
我正在尝试将GNU parallel大量文件发布到Web服务器.在我的目录中,我有一些文件:
file1.xml
file2.xml
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的shell脚本:
#! /usr/bin/env bash
CMD="curl -X POST -d@$1 http://server/path"
eval $CMD
Run Code Online (Sandbox Code Playgroud)
脚本中还有其他一些东西,但这是最简单的例子.我试图执行以下命令:
ls | parallel -j2 script.sh {}
Run Code Online (Sandbox Code Playgroud)
这些GNU parallel页面显示为对目录中的文件进行操作的"正常"方式.这似乎将文件的名称传递给我的脚本,但curl抱怨它无法加载传入的数据文件.但是,如果我这样做:
find . -name '*.xml' | parallel -j2 script.sh {}
Run Code Online (Sandbox Code Playgroud)
它工作正常.在我的脚本中传递参数的方式ls和find方法之间是否存在差异?或者我是否需要在该脚本中执行其他操作?
我在Bash中有一个while循环处理如下:
while IFS=$'\t' read -r -a line;
do
myprogram ${line[0]} ${line[1]} ${line[0]}_vs_${line[1]}.result;
done < fileinput
Run Code Online (Sandbox Code Playgroud)
它从具有此结构的文件中读取,以供参考:
foo bar
baz foobar
Run Code Online (Sandbox Code Playgroud)
等等(制表符分隔).
我想使用GNU parallel并行化这个循环(因为条目很多,处理速度很慢),但是我不知道如何将每一行分配给数组,就像我在这里做的那样.
什么是可能的解决方案(GNU并行工作的替代方案)?
我有一个bash脚本,其函数需要与不同的参数并行运行.我需要知道是否至少有一个执行失败(返回非零) - 无论多少失败都无关紧要.
该命令接受执行的参数数组.由于高负载,我需要将并发限制为4次并发运行.我还需要在父进程(运行bash脚本的进程)中打印日志
这是我正在运行的功能:
function run_and_retry {
EXIT_STATUS=0
$COMMAND || EXIT_STATUS=$?
if [ $EXIT_STATUS -ne 0 ]; then
EXIT_STATUS=0
$COMMAND || EXIT_STATUS=$?
fi
return $EXIT_STATUS
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用GNU parallel和xargs,并遇到了两个问题.
使用xargs :(无法从中获取退出状态,当我在TravisCI中运行它时也无效)
PARAMETERS=(first-parameter second-parameter third-parameter)
export -f run_and_retry
echo "${PARAMETERS[@]}" | xargs -P 4 -n 1 -I {} bash -c "run_and_retry {}"
Run Code Online (Sandbox Code Playgroud)
使用GNU并行:
PARAMETERS=(first-parameter second-parameter third-parameter)
export -f run_and_retry
parallel -j 4 -k --lb 2 run_and_retry {} ::: echo "${PARAMETERS[@]}"
Run Code Online (Sandbox Code Playgroud) 我在服务器上有一大堆文件,我想将它们上传到S3.这些文件以.data扩展名存储,但实际上它们只是一堆jpeg,png,zip或pdf.
我已经编写了一个简短的脚本,它找到了mime类型并将它们上传到S3上,但是它运行起来很慢.有没有办法使用gnu parallel进行下面的运行?
#!/bin/bash
for n in $(find -name "*.data")
do
data=".data"
extension=`file $n | cut -d ' ' -f2 | awk '{print tolower($0)}'`
mimetype=`file --mime-type $n | cut -d ' ' -f2`
fullpath=`readlink -f $n`
changed="${fullpath/.data/.$extension}"
filePathWithExtensionChanged=${changed#*internal_data}
s3upload="s3cmd put -m $mimetype --acl-public $fullpath s3://tff-xenforo-data"$filePathWithExtensionChanged
response=`$s3upload`
echo $response
done
Run Code Online (Sandbox Code Playgroud)
此外,我确信这个代码一般可以大大改进:)反馈提示将不胜感激.
我正在使用此脚本下载文件:
parallel --progress -j16 -a ./temp/img-url.txt 'wget -nc -q -P ./images/ {}; wget -nc -q -P ./images/ {.}_{001..005}.jpg'
Run Code Online (Sandbox Code Playgroud)
是不是可以不下载文件,只是在远程端检查它们,如果存在则创建一个虚拟文件而不是下载?
就像是:
if wget --spider $url 2>/dev/null; then
#touch img.file
fi
Run Code Online (Sandbox Code Playgroud)
应该工作,但我不知道如何将此代码与GNU Parallel结合起来.
编辑:
根据Ole的回答,我写了这段代码:
#!/bin/bash
do_url() {
url="$1"
wget -q -nc --method HEAD "$url" && touch ./images/${url##*/}
#get filename from $url
url2=${url##*/}
wget -q -nc --method HEAD ${url%.jpg}_{001..005}.jpg && touch ./images/${url2%.jpg}_{001..005}.jpg
}
export -f do_url
parallel --progress -a urls.txt do_url {}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但它对某些文件失败了.我无法找到为什么它适用于某些文件的一致性,为什么它对其他文件失败.也许它有最后一个文件名的东西.第二个wget尝试访问当前url,但之后的touch命令根本不会创建desidered文件.第一个wget总是(正确地)下载没有_001.jpg,_002.jpg的主图像.
示例urls.txt:
http://host.com/092401.jpg(工作正常,_001.jpg .._ 005.jpg下载) http://host.com/HT11019.jpg(不起作用,只下载主图像)