Reputation: 331
I want to create an array from a list of words. so, i'm using this code:
for i in {1..$count}
do
array[$i]=$(cat file.txt | cut -d',' -f3 | sort -r | uniq | tail -n ${i})
done
but it fails... in tail -n ${i}
I already tried tail -n $i
, tail -n $(i)
but can't pass tail the value of i
Any ideas?
Upvotes: 1
Views: 232
Reputation: 246877
Instead of reading the file numerous times, use the built-in mapfile
command:
mapfile -t array < <(cut -d, -f3 file.txt | sort -r | uniq)
Upvotes: 1
Reputation: 3085
Just to elaborate on previous answers, this occurs because the 'brace expansion' is the first part of bash's parsing, and never gets repeated: when the braces are expanded, the '$count' is just a piece of text and so the braces are left as is. Then, when '$count' is expanded to a number, the brace expansion never runs again. See here.
If you wanted for some reason to force this brace expansion to happen again, you can use 'eval':
replace the {1..$count}
with $(eval echo {1..${count}})
Better, in your case, to do as anubhava suggests.
Upvotes: 1
Reputation: 785286
It fails because you cannot use a variable in range directive in shell i.e. {1..10}
is fine but {1..$n}
is not.
While using BASH you can use ((...))
operators:
for ((i=1; i<=count; i++)); do
array[$i]=$(cut -d',' -f3 file.txt | sort -r | uniq | tail -n $i)
done
Also note removal of useless use of cat from your command.
Upvotes: 1
Reputation: 54551
Your range is not evaluated the way you are thinking, e.g.:
$ x=10
$ echo {1..$x}
{1..10}
You're better off just using a for loop:
for ((i = 1; i <= count; i++))
do
# ...
done
Upvotes: 1