GNU Parallel - redirect output to a file with a specific name

9.9k views Asked by At

In bash I am running GnuPG to decrypt some files and I would like the output to be redirected to a file having the same name, but a different extension. Basically, if my file is named

file1.sc.xz.gpg

the file which comes out after running the GnuPG tool I would like to be stored inside another file called

file1.sc.xz 

I am currently trying

find . -type f | parallel "gpg {} > {}.sc.xz"

but this results in a file called file1.sc.xz.gpg.sc.xz. How can I do this?

Later edit: I would like to do this inside one single bash command, without knowing the filename in advance.

3

There are 3 answers

0
Ole Tange On

If file names are guaranteed not to contain \n:

find . -type f | parallel gpg {} '>' {.}
parallel gpg {} '>' {.} ::: *

If file names may contain \n:

find . -type f -print0 | parallel -0 gpg {} '>' {.}
parallel -0 gpg {} '>' {.} ::: *

Note that opposite shell variables GNU Parallel's substitution strings should not be quoted. This will not create the file 12", but instead 12\" (which is wrong):

parallel "touch '{}'" ::: '12"'

These will all do the right thing:

parallel touch '{}' ::: '12"'
parallel "touch {}" ::: '12"'
parallel touch {} ::: '12"'
17
Maxim Egorushkin On

You can use bash variable expansion to chop off the extension:

$ f=file1.sc.xz.gpg
$ echo ${f%.*}
file1.sc.xz

E.g.:

find . -type f | parallel bash -c 'f="{}"; g="${f%.*}"; gpg "$f" > "$g"'

Alternatively, use expansion of parallel:

find . -type f | parallel 'gpg "{}" > "{.}"'
2
Charles Duffy On
find . -type f -print0 | \
  xargs -P 0 -n 1 -0 \
    bash -s -c 'for f; do g=${f%.*}; gpg "$f" >"$g"; done' _

Right now this processes only one file per shell, but you could trivially modify that by changing the -n value.