Using sed with parallel gives empty output when redirecting to file

3

I'm using the zsh shell. I am trying to use sed to substitute some text in many files, using parallel to speed up the process. When I tested this on one file and let the command output go to stdout I saw the expected result. When I tried to redirect that output to a file I got an empty file. What's going on? Here's a trivial example using a single made-up data file you can cut and paste to illustrate...

setopt interactivecomments
#  In this trivial example it is obviously non-sensical
#  to use parallel, but in reality I have many files...

#  Some very simple input data...
paste <(printf "%s\n" `seq 1 4`) <(printf "%s\n" `seq 1 4`) > ./input.txt
#  This looks like:
#1       1
#2       2
#3       3
#4       4


#  Pass data file to parallel and use sed to substitute.
#  e.g. want to replace line '3 3' with '3 33'
#  Output goes to stdout & seems correct...
z=`find ./input.txt`
echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/"'
#1       1
#2       2
#3       33    ===> correct replacement
#4       4

# But redirecting to a file leads to empty file...
echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/" > {//}/result.txt'

# Empty file
cat ./result.txt

What gives? Am I specifying something incorrectly?

I am using:

  • Ubuntu 12.04.4 LTS
  • GNU parallel 20130522
  • GNU sed version 4.2.1
  • zsh 4.3.17

Simon O'Hanlon

Posted 2014-06-10T11:00:47.073

Reputation: 135

Answers

3

When using redirection inside the command for parallel, you have to use {} to put the input at the right place, as parameter for sed:

echo "$z" | parallel 'sed "s/\(^3.*3\)/\13/" {} > {//}/result.txt'

Additionally, if {//} (or any other replacement string) is used, parallel does not append the input at the end of the command automatically. (In this case that would be wrong anyways, as it would be after the redirection. )

Essentially, the code in the question runs

sed "s/(^3.*3\)/\13/" > ./result.txt

but it needs to be

sed "s/(^3.*3\)/\13/" ./input.txt > ./result.txt

Adaephon

Posted 2014-06-10T11:00:47.073

Reputation: 3 864

1Not entirely correct: If any replacement string (e.g. {//}) is used, then {} will not be appended. So the code runs: sed "s/(^3.*3)/\13/" > ./result.txt (which is clearly also wrong. Use --dry-run to confirm). So Adaephon's answer is correct, but for the wrong reason. – Ole Tange – 2014-06-10T20:34:24.390

@OleTange Thanks for the heads-up. I edited the answer accordingly. – Adaephon – 2014-06-11T18:19:07.563