1

I have files from 1 to n, which look like the following:

sim.o500.1 
sim.o500.2
.
.
.
sim.o500.n

Each file contains only one line. Now I want to concatenate them in the order from 1 to n.

I tried cat sim.o500.* > out.dat. Sadly this does not work if e.g. n is larger than 9, because this concatenates then sim.o500.1 followed by sim.o500.10and not sim.o500.1 followed by sim.o500.2.

How can I loop through the file names using the numeric order?

fedorqui
  • 275,237
  • 103
  • 548
  • 598
nerdizzle
  • 424
  • 4
  • 17
  • Related: [What's the best way to join files after splitting?](http://unix.stackexchange.com/q/24630/30580) – legends2k Apr 01 '15 at 15:07

5 Answers5

2

Since * expands in a non-numeric-sorted way, you'd better create the sequence yourself with seq: this way, 10 will coome after 9, etc.

for id in $(seq $n)
do
   cat sim.o500.$id >> out.dat
done

Note I use seq so that you are able to use a variable to indicate the length of the sequence. If this value happens to be fixed and known beforehand, you can directly use range expansion writing the n value like: for id in {1..23}.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
2
echo {1..12}

would print

1 2 3 4 5 6 7 8 9 10 11 12

You can use this Bash's range expansion feature to your advantage.

cat sim.o500.{1..20}

would expand to the filenames in numerically sorted order and it is terse (lesser keystrokes).

One caveat is that you may hit the "too many arguments" error if the file count exceeds the limit.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • This is nice! I was mentioning range expansion in my answer but didn't think about doing it this way. Simple and nice, +1! – fedorqui Apr 01 '15 at 15:08
  • Thank you, I didn't know it actually, I got this tip from the _Related_ question commented under the question. In a sense, your's is better since it doesn't have the argument limit issue. – legends2k Apr 01 '15 at 15:11
1

Try

ls sim.o500.* | sort -t "." -n -k 3,3 | xargs cat > out.dat

Explanation:

ls

ls sim.o500.* will produce a list of file names, matching pattern sim.o500.*, and pass it over the pipe to sort

sort

sort -t "." -n -k 3,3 will grab all those file names and sort them as numbers (-n) in descending order using 3rd column (-k 3,3) and pass it over the pipe to xargs.

-t "." tells sort to use . as a separator, instead of spacing characters, as it does by default. So, having sim.o500.5 as an example, the first column would be sim, the second column: o500 and the third column: 5.

xargs

xargs cat > out.dat will start cat and append all lines, received via pipe from sort as command arguments. It does something like:

execute("cat > out.dat sim.o500.1 sim.o500.2 sim.o500.3 ... sim.o500.n")
GreenScape
  • 7,191
  • 2
  • 34
  • 64
0
> out.dat
for i in `ls -v sim*`
do
echo $i
cat $i >> out.dat
done
kjohri
  • 1,166
  • 11
  • 10
0

If you have all the files in a folder try to use this command:

cat $(ls -- sim* | sort) >> out.dat
Oibaf it
  • 1,842
  • 16
  • 9