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. 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? 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. Commented Aug 7, 2014 at 16:00
  • @Ryan you could begin with cat /dev/null > Out.txt and have >> on all invocations of ./myprogram. 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... 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. 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.