Bash – How to decode a list of base64-encoded file names

base64bashechoxargs

I have a list of base64-encoded file names in the pattern of {base64-encoded part here}_2015-11-12.pdf. I'm trying to decode that list of files and return it on the command line as another list, separated by newlines. Here's what I'm trying now:

find . -name "*_*" -printf "%f\0" | sed 's/_....-..-..\.pdf//g' | xargs -0 -i echo "{}" | base64 -d

I think what I'm doing here is . . .

  1. finding the files, printing out only the file's name (i.e., stripping off the "./" prefix) separated by a null character
  2. using sed to preserve only the base64-encoded part (i.e., removing the _2015-11-12.pdf part of the file's name)
  3. using xargs to ostensibly pass each file name to echo
  4. then decoding the value returned by echo.

The result of that is apparently a big string of all of the base64-decoded file names, each name separated by a null character, with the entire string followed by a newline. The desired result would be each individual decoded file name on a line by itself.

I've tried all kinds of tricks to try and fix this but I haven't found anything that works. I've tried ... | base64 -d | echo, ... | base64 -d && echo, etc., trying to insert a newline at various points along the way. It seems like by the time the values end up at | base64 -d, they are all processed at once, as a single string. I'm trying to find a way to send each value to base64 -d one at a time, NOT as a monolithic list of file names.

Best Answer

Just add the base64 encoding of newline (Cg==) after each file name and pipe the whole thing to base64 -d:

find . -name "*_*" -printf "%f\n" |
  sed -n 's/_....-..-..\.pdf$/Cg==/p' |
  base64 -d

With your approach, that would have to be something like:

find . -name "*_*" -printf "%f\0" |
  sed -zn 's/_....-..-..\.pdf$//p' |
  xargs -r0 sh -c '
    for i do
      echo "$i" | base64 -d
    done' sh

as you need a shell to create those pipelines. But that would mean running several commands per file which would be quite inefficient.

Related Question