Some comments about allend's script.
1)
Code:
for (( i=1; i<${#line[*]}; i++ )); do
When iterating over an array, there's a more convenient option.
Code:
for i in "${!line[@]}" ; do
This outputs a list of all the available index numbers. It's particularly convenient for iterating over sparse arrays.
2)
Code:
if [[ $i < 5 ]]; then
This is just wrong. First of all, when inside square brackets, "
<" is a
string comparison operator. Try comparing the numbers 99 and 100 with it, for example.
The proper operator to use for integers is "
-lt". Or even better, use actual arithmetic evaluation brackets.
Code:
if [[ $i -lt 5 ]]; then #correct
if (( i < 5 )); then #best
http://mywiki.wooledge.org/ArithmeticExpression
http://mywiki.wooledge.org/BashFAQ/031
3)
Code:
echo -ne "\t"${line[$i]};
Put the quotes around the entire string. You should never leave quotation marks off a parameter expansion unless you explicitly want the resulting string to be word-split by the shell. Globbing patterns get expanded too.
Code:
echo -ne "\t${line[$i]}"
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
In any case, we can make the script much shorter and cleaner. Just use a single, simple
printf statement to define the line format, and the array
range expansion operators.
Code:
#!/bin/bash
while read -a line || [[ -n $line ]]; do
printf '%s\t%s\t%s\t%s\t%s %s\n' "${line[@]:0:5}" "${line[*]:5}"
done < "$1"
exit 0
Notice in particular how I used "
@" for the first five array entries, and "
*" for the remainder. "
@" means it outputs the vales 0-4 as separate entities, but "
*" prints the values 5+ as a single string, so
printf reads them as only one "
%s" value.
I also set the filename to "
$1" so that it can be run dynamically. It's not generally advisable to store things like filenames inside the script itself. Scripts are for containing code, not data.
Edit: One last modification. When using a
while+read loop, if the input file doesn't contain a final newline, then the last line
won't get processed. So I added an additional test to the while loop to capture and process it.