You normally can pipeline the operations

a | b | c

where b takes input from a and sends it to c. It has only one input, generated by a. But what if I want to replace a header in file b. I therefore echo a new header (this is a operation). Additionally, I cat b | dd bs=1 skip=header_size to strip the header from the file. This is bc operation. Now I have two outputs, produced by echo new_header and cat. How do I concatenate them?

  • If you do [c(b)](a), then c(b) must have a command as output. In which case, my answer is what you need. – muru Jun 22 '16 at 16:49
  • Is b a binary file? Or is it a shell script of some sort? – muru Jun 22 '16 at 16:58
  • @muru That is shebang java jar. That is, text header with zip tail. – Little Alien Jun 22 '16 at 17:01
  • This question continues to make no sense. What does a shebang have to do with a java jar? You say a outputs the new header, but then piping a's output to the b|c command makes no sense - you would want something like a; b|c instead. This is an XY problem: meta.stackexchange.com/questions/66377/what-is-the-xy-problem Please post the actual problem instead of an imagined half-solution. – muru Jun 22 '16 at 17:05
  • 1
    I also don't understand what your actual use case is. You can mix standard input, files, and process substitutions on the cat command line if you wish e.g. echo "new header" | cat - <(dd if=b bs=1 skip=$header_size). A more elegant solution might use a here-document. Again, it would be helpful to give us a complete minimal working example. – steeldriver Jun 22 '16 at 17:54

You asked "How do I concatenate them?" - and the answer is, quite simply, with cat:

       cat - concatenate files and print on the standard output

       cat [OPTION]... [FILE]...

       Concatenate FILE(s), or standard input, to standard output.

Note in particular that its inputs can include standard input, not just files. So for example, you can:

  1. mix standard input and files

    echo "new text" | cat - oldfile > newfile
  2. mix standard input and process substitutions

    echo "new text" | cat - <(some_command oldfile) > newfile

    for example,

    echo "new header" | cat - <(dd if=oldfile bs=1 skip=$header_size) > newfile

Alternatively, you could use a here document and embed the command output using command substitution - that's probably a better option if your replacement text consists of more than a single line e.g.

$ cat > newfile << EOF
$(dd if=oldfile bs=1 skip=$header_size)
  • Are you sure that EOF spans beyond the dd command, embracing it? – Little Alien Jun 22 '16 at 18:41

If you don't like shell process substitution voodoo you can also use a simple redirection of a command group:

{ printf '%s\n' 'header line 1' 'header line 2' ...; tail -c +$(($header_size+1)) old-file.txt; } > new-file.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.