14

I have a text file which each line is a one word coded base64 separely. Now I want to decode it. I'm trying to use base64 command line, but I'm getting all the words in only one line, I want one per line.

For example, my file is:

Y2F0Cg==
ZG9nCg==
aG91c2UK

I want as result:

dog
cat
house

But I'm getting:

dogcathouse

I think xargs could help, but I'm not getting the point.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
tpcordeiro
  • 441
  • 1
  • 6
  • 13
  • You might want to change the title of the question since it's not actually about looping through a file. – l0b0 Jun 20 '13 at 12:57
  • @l0b0: I don't think so. because OP thought that it was required to loop. However, there was a better solution available. – anishsane Jun 20 '13 at 13:08

4 Answers4

16

Use base64 --decode together with a loop:

$ while IFS= read -r line; do echo "$line" | base64 --decode; done < file
cat
dog
house
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 3
    For me, this consumed all the newlines, just as the other solution. Had to add an `echo "";` after `echo $line | base64 --decode;`. – caw Aug 09 '18 at 07:03
  • @caw my loop was a bit bad, I just added some safety into it. Do you want to check if it works fine to you now? – fedorqui Aug 09 '18 at 07:28
  • Thanks, but that doesn’t actually make any difference. After some short debugging, I found the crucial element here: If you put the result of `echo "dog" | base64` into each line, your code works. But if you put the result of `echo -n "dog" | base64` (note the `-n` option) into each line, it does not work. So it requires the actual (Base64-encoded) data to end with a newline already. So for all possible inputs, your code works the same way as the simple `base64 -d file`. Anyway, adding that additional `echo ""` for a newline, as I suggested before, makes your code work in the other cases. – caw Aug 09 '18 at 07:47
  • @caw well, `base64 --decode` is the same as `base64 -d`. Regarding the use of `echo -n`, it means "do not output the trailing newline", so it is equivalent to `printf` (you need `printf "bla\n"` to have the new line). In any case, I fail to see what is what you are looking for in here: having a new line at the end of the file? – fedorqui Aug 09 '18 at 07:53
  • I know these commands and parameters. My point was that your solution appears to provide exactly the same results as the simple `base64 -d file` suggested in the other answer, while being more complex. So there doesn’t seem to be any situation when your solution may be preferable to the other one. To emphasize what does not work (or what I’m looking for in here): If your file consists of lines with the Base64-encoded versions of `dog`, `cat` and `house` – and *not* `dog\n`, `cat\n` and `house\n` – your solution (and the other one) will show exactly the problem that the question tried to solve. – caw Aug 09 '18 at 07:59
  • @caw OK, I see. Probably this has to do with [OP's comment](https://stackoverflow.com/questions/17214038/pipe-each-line-of-a-file-to-a-command/17214061?noredirect=1#comment24936429_17214064) stating that their file was not entirely base64 coded, so they may want to decode line by line to get as much lines decoded as possible. That is, my solution worked to the OP for that case, but for the general one (like yours) `base64 -d file` suffices. Note in fact that [I removed my answer for a while](https://stackoverflow.com/posts/17214061/revisions), only then I saw OP needed my approach. – fedorqui Aug 09 '18 at 08:06
5

This works for me in base64 8.13:

base64 --decode test.txt

No need to split the file. Which version are you using?

l0b0
  • 55,365
  • 30
  • 138
  • 223
  • Good one, I thought it was necessary to loop through the file. – fedorqui Jun 20 '13 at 12:52
  • 5
    I used this, but not worked. I think it is because the file was not entirely base64 coded. In fact, each word was coded separely, and then it was put together in file. – tpcordeiro Jun 20 '13 at 13:06
3

You can use Python for that (no need for reading each line):

python -m base64 -d foo.txt
kenorb
  • 155,785
  • 88
  • 678
  • 743
1

You can use bash here-document <<< for this.

cat FILE | xargs -I{} bash -c 'base64 -d <<< {}'
Ryan
  • 4,594
  • 1
  • 32
  • 35