fpilee
fpilee

Reputation: 2098

Joining files with cat

i'm doing a script to download one file in multiple parts, i'm in the part of joining that files. I can join the parts outside of the script with

cat name.part{0..4} > name.ext

But, if i use this in the script

cat $filename.part{0..$N} > $filename

i get:

cat: Bitcoin-960x623.jpg.part{0..5}: No such file or 

Upvotes: 0

Views: 415

Answers (4)

Digital Trauma
Digital Trauma

Reputation: 15996

{0..4} is a brace expansion; $N is a variable expansion. Your expression doesn't work as you expect because brace expansion happens before variable expansion:

The order of expansions is: brace expansion, tilde expansion, parameter, variable, and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and filename expansion.

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions

You can use the seq command instead of a brace expansion to generate the required filenames up to arbitrary N:

$ filename=myfile
$ N=4
$ cat $(seq -f "$filename.part%g" 0 $N) > name.ext
$

In the unlikely event seq -f is unavailable, you can use a for loop one-liner instead:

$ cat $(for ((i=0; i<N; i++)); do echo "$filename.part$i"; done) > name.ext
$

Upvotes: 4

kojiro
kojiro

Reputation: 77127

Assertion: I'm going to argue that this answer is better. (Something I don't do often or lightly.) My rationale is that all of the other answers here at the time of this edit just expand to a range of integers, whether the files matching those integers exist or not. By using glob expansions you guarantee you will not encounter No such file or directory from cat. In all other cases with brace expansion, eval, seq and a for loop you'd have to explicitly check.

If there are fewer than 10 total filenames:

cat "$filename".part[0-9]

will expand as a glob to however many names there are. This is a fast and portable solution, but obviously limited. If there are more than 10 then that pattern will only match the ones with one digit, so you have to get a bit wilier and use extglob:

shopt -s extglob
cat "$filename".part+([0-9])

should do it, but this will only work for the Bourne-Again SHell. (That said, several other modern shells have expansion capabilities similar to extglob.)

Upvotes: 2

fpilee
fpilee

Reputation: 2098

I solved with this.

for (( k=0 ; k<=$N ; k++ ))
do
cat $filename.part$k >> $filename
done

Upvotes: 3

anubhava
anubhava

Reputation: 785196

You cannot use variables inside curly braces in shell. eval can be used here:

eval "$filename.part{0..$N} > $filename"

Upvotes: 2

Related Questions