LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-28-2014, 06:42 PM   #1
kostas85
LQ Newbie
 
Registered: Apr 2014
Posts: 3

Rep: Reputation: Disabled
Help on using parallel shell command


Hello all,

I'm trying to parallelize the following shell script:

Code:
for ((i=0,i<=100,i+=4));do
 cat ${filelist1[@]:$i:4} ${filelist2[@]:$i:4} > ${filelist3[@]:$i:4} 
done

but I have troubles when I use the parallel command

Code:
for ((i=0,i<=100,i+=4));do
 f1in=("${f1in[@]}" "`echo ${filelist1[@]:$i:4}`")
 f2in=("${f2in[@]}" "`echo ${filelist2[@]:$i:4}`")
 fout=("${fout[@]}" "`echo ${filelist3[@]:$i:4}`")
done

parallel --xapply cat {1} {2} ">" {3} ::: "f1in[@]" ::: "f2in[@]" ::: "fout[@]"
The above interprets the files given in, say f1in[0], as a single file. So cat searches for a single file that doesn't exist and prints an error message. Probably the solution is really simple but I'm not an experienced shell programmer. Could you please propose some workarounds. Many thanks in advance!

Kostas
 
Old 04-28-2014, 08:58 PM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
`` is the inverse of echo, but echo joins all its arguments together with space. Just cancel them out, this keeps the arguments separated:
Code:
 f1in=("${f1in[@]}" "${filelist1[@]:$i:4}")
 
1 members found this post helpful.
Old 04-29-2014, 02:40 AM   #3
kostas85
LQ Newbie
 
Registered: Apr 2014
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks for your answer!!! I'm sorry I made a mistake in the code I posted... the 4+4 files should be concatenated to a single file so:

Code:
for ((i=0,i<=100,i+=4));do
 cat ${filelist1[@]:$i:4} ${filelist2[@]:$i:4} > ${filelist3[@]:$i} 
done
and similarly:

Code:
for ((i=0,i<=100,i+=4));do
 f1in=("${f1in[@]}" "`echo ${filelist1[@]:$i:4}`")
 f2in=("${f2in[@]}" "`echo ${filelist2[@]:$i:4}`")
 fout=("${fout[@]}" "`echo ${filelist3[@]:$i}`")
done
Each process should get 4 files from list filelist1, 4 from list filelist2 and join them to one file from filelist3

I used the echo to generate the "list" of items ${filelist1[@]:$i:4} inside the arrays f1in,f2in, since without the echo they are treated as seperate elements. The problem is that when I do as a test:

Code:
cat ${f1in[0]} ${f2in[0]} > ${fout[0]}
It works normally.. However, when processed from parallel it says that it cannot find the files since as you said the arguments are joined with space.
I'm sorry for the mistake... Any ideas ?
 
Old 04-29-2014, 10:06 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by kostas85 View Post
I used the echo to generate the "list" of items ${filelist1[@]:$i:4} inside the arrays f1in,f2in, since without the echo they are treated as seperate elements. The problem is that when I do as a test:

Code:
cat ${f1in[0]} ${f2in[0]} > ${fout[0]}
It works normally..
Ah, you really want a 2 dimensional array of file names. When you use ${f1in[0]} unquoted, the shell splits the value by whitespace, so that's a way of faking the inner array. Shell script doesn't have real 2D arrays, so you should consider writing this is in some other language. You can achieve the faking by explicitly telling parallel to call a shell:
Code:
parallel --xapply sh -c 'cat $0 $1 > "$2"' {1} {2} {3} ::: "f1in[@]" ::: "f2in[@]" ::: "fout[@]"
By the way, to join the arguments with space you can use "${filelist1[*]:$i:4}" instead of "`echo ${filelist1[@]:$i:4}`"
 
1 members found this post helpful.
Old 04-29-2014, 03:08 PM   #5
kostas85
LQ Newbie
 
Registered: Apr 2014
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thank you!!! It worked like a charm!!!

However I found in my previous post some errors... The part I posted is a part of a much larger script that I faulty reduced...

Here is the final working version with our suggestions:

--------
SERIAL
--------

Code:
#
# Generate three lists of files: filelist1 filelist2 filelist3
# Input to cat are: filelist1 and filelist2
# the output file should be named the ith element of filelist3
#
# filelist1 -> the files taken by 4 should be at the beginning of the resulting file
# filelist2 -> the files taken by 4 should follow
#
for ((i=0,i<=99,i+=4));do
 cat ${filelist1[@]:$i:4} ${filelist2[@]:$i:4} > ${filelist3[@]:$i} 
done

-----------
PARALLEL
-----------

Code:
#
# Generate three lists of files: filelist1 filelist2 filelist3
# Input to cat are: filelist1 and filelist2
# the output file should be named the ith element of  filelist3
#
# filelist1 -> the files taken by 4 should be at the beginning of the resulting file
# filelist2 -> the files taken by 4 should follow
#
function local_cat()
{
  cat $1 $2 > $3
}

export -f local_cat

for ((i=0,i<=99,i+=4));do
 f1in=("${f1in[@]}" "${filelist1[*]:$i:4}")
 f2in=("${f2in[@]}" "${filelist2[*]:$i:4}")
 fout=("${fout[@]}" "${filelist3[@]:$i}")
done

parallel --xapply local_cat {1} {2} {3} ::: "${f1in[@]}" ::: "${f2in[@]}" ::: "${fout[@]}"
Thanks again! You really helped me a lot!!!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Nvidia and ARM: It's a parallel, parallel, parallel world LXer Syndicated Linux News 0 03-21-2013 06:10 PM
[SOLVED] Executing a command in parallel | GNU parallel or xargs the_gripmaster AIX 3 05-08-2012 07:41 AM
is there any shell command to read and write data from parallel and serial port? baosheng Linux - Hardware 2 01-13-2007 08:35 PM
How to execute two shell scripts in parallel Pavitra.v Linux - General 4 09-16-2006 05:59 AM
parallel port and shell script legolin Programming 1 09-05-2004 12:53 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration