Search code examples
regexbashgnu-parallel

String replacement in GNU-Parallel when using multiple input streams


I know how to perform perl-style string replacement in parallel and I love it, but I wanted to know if I can use it when I have 2 input streams and apply the replacement for just a specific input. For example, say that I run the following command:

$ parallel echo "First name: {1}, Last name: {2}" ::: John Jane :::+ Doe Smith

The output is :

First name: John, Last name: Doe
First name: Jane, Last name: Smith

Say I want to initialise the surname only with a replacement string:

$ parallel --rpl "{init} s:(\w).+:\1:" echo "First name: {1}, Last name: {init}" ::: John Jane :::+ Doe Smith

parallel will actually replace both input streams to generate the following output:

First name: John, Last name: J D
First name: Jane, Last name: J S

(Notice the extra J in the last name).
Is there any way to tell parallel which input I want to operate on?

UPDATE

Answering my question, I had an epiphany (or recall) and I tried adding the number of my required input inside the curly brackets when calling the replacement string, and it did exactly what I wanted:

$ parallel --rpl "{init} s:(\w).+:\1:" echo "First name: {1}, Last name initial: {2 init}" ::: John Jane :::+ Doe Smith
First name: John, Last name: D
First name: Jane, Last name: S

Similar to this question, is it possible to use the predefined replacement string as input for my replacement or do I need to create the full replacement from the original input?
For example, can I somehow use the replacement string {/} to remove the path and then do a replacement on the base filename without the path:

ls -1 /home/user/*_non-important.txt | parallel --rpl "{mybasename} s:_non-important.txt::" echo "{mybasename}"

Thanks, Ido


Solution

  • Similar to this question, is it possible to use the predefined replacement string as input for my replacement or do I need to create the full replacement from the original input?

    You need to create the full replacement from the original input. You can find the definition in man parallel under --rpl:

    --rpl '{/} s:.*/::'
    

    So:

    ... | parallel --rpl '{mybasename} s:.*/::; s:_non-important.txt::' echo {mybasename}
    

    Remember that --rpl definitions can be put in ~/.parallel/config