3

Currently I use multiple lines to append content into a combined file, e.g.

./myprogram 1.txt > Out.txt # Overwrite for the 1st file
./myprogram 2.txt >> Out.txt
./myprogram 3.txt >> Out.txt
./myprogram 4.txt >> Out.txt

Is it possible to replace by one-liner?

4
  • 4
    I will never understand why people insist on magical one liners instead of putting an easy to understand solution into a shell script.
    – Sven
    Commented Aug 7, 2014 at 11:21
  • Because it is error prone, the first line is a single ">", and the rest of lines are ">>", I've several times used ">>" in the first line due to copy and paste, so I am looking for more elegant solution. does it make sense to you?
    – Ryan
    Commented Aug 7, 2014 at 15:52
  • Creating a shell script with good formatting, indentation and comments is better anyway because it's easier to understand, and therefore less error prone then an endless one-liner. If you need to do the above more than once, it will also save a lot of time.
    – Sven
    Commented Aug 7, 2014 at 16:00
  • @Ryan you could begin with cat /dev/null > Out.txt and have >> on all invocations of ./myprogram.
    – MattBianco
    Commented Aug 8, 2014 at 14:46

5 Answers 5

8
(./myprogram 1.txt; ./myprogram 2.txt; ./myprogram 3.txt; ./myprogram 4.txt) > out.txt
1
  • +1 Bonus, this works in bash, sh, csh/tcsh, zsh, and probably more...
    – Chris S
    Commented Aug 8, 2014 at 13:46
5

It depends on what you want to do and how your program handle input args.

But let's say you have /path/to/myprogram.sh who look like this one :

#!/bin/bash
echo "Processing file ${1?missing input file}"

You could do the following

find /path/to/inputfiles -name "*.txt" -exec /path/to/myprogram.sh {} \; > Out.txt

Or within bash (or any Bourne-like shell):

for i in *.txt; do /path/to/myprogram.sh "$i"; done > Out.txt

(I use for-loop or find because it will be much more convenient if you have 1000 input files instead of the 4 files in your example)

1
  • 1
    careful with the *.txt if Out.txt already exists.
    – MattBianco
    Commented Aug 8, 2014 at 14:44
1

Very similar to Per's answer, but maintains the layout of the original:

{
    ./myprogram 1.txt
    ./myprogram 2.txt
    ./myprogram 3.txt
    ./myprogram 4.txt
} > Out.txt

http://www.gnu.org/software/bash/manual/bashref.html#Command-Grouping

0

myprogram-wrapper.sh:

#!/bin/sh -
while test $# -ge 1
do
  ./myprogram $1
  shift
done

invoke with ./myprogram-wrapper.sh 1.txt 2.txt 3.txt 4.txt > Out.txt

To make a reusable wrapper:

#!/bin/sh -
prog=$1
shift
while test $# -ge 1
do
  ${prog} $1
  shift
done

and invoke like wrapper ./mycommand 1.txt 2.txt 3.txt 4.txt > Out.txt

This is of course cheating, since the script itself is not a oneliner, but I thought you might like it anyway.

0

I find this solution more elegant:

FILE=/tmp/file.log

exec >> $FILE
./myprogram 1.txt
./myprogram 2.txt
./myprogram 3.txt
./myprogram 4.txt
exec 1<&2

echo 'Normal output has returned!'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .