Reputation: 18429
I have a file named SOURCE, and I want to create a file named TARGET of a specific length, containing copies of SOURCE. TARGET's length is not necessarily an integer multiple of SOURCE's length. I want to do this using bash on Linux.
My first try was this:
while true; do cat SOURCE; done | head -c $TARGET_LENGTH > TARGET
That hangs after writing the specified number of bytes to TARGET. How do I make it not hang? (I suspect I'm missing a detail around how pipes and signals work.)
Edit: I know that while true
runs forever, but I expected the head command to shut everything down after consuming the specified number of bytes.
Upvotes: 3
Views: 256
Reputation: 208
You need to break out of the while loop.
For example, using a temp file, fill it until it's the same size or larger than your target length, then break out of the loop and use head -c to output the temp file into your target gile.
while true; do
cat $SOURCE_FILE >> /tmp/temp.out;
TMP_LENGTH=$(wc -c /tmp/temp.out |awk '{print $1}')
if [ $TMP_LENGTH -ge $TARGET_LENGTH ]; then
break
fi
done
head -c $TARGET_LENGTH /tmp/temp.out > $TARGET_FILE
Upvotes: 0
Reputation: 46833
How about this?
while cat SOURCE; do true; done | head -c "$TARGET_LENGTH" > TARGET
Upvotes: 6
Reputation: 181
Here's a longwinded solution... Can someone do something more elegant?
echo > $TARGET
sourceLength=`wc -c $SOURCE | awk '{print $1}'`
let loops=$(( $TARGET_LENGTH/$sourceLength ))
let n=0;
while [ $n -lt $loops ]; do
let n=$(( $n+1 )) || exit 1
cat $SOURCE >> $TARGET
done
let mod=$(( $TARGET_LENGTH % $sourceLength ))
head -c $mod $SOURCE >> $TARGET
Upvotes: 1