0

I wanted to loop over the lines of a text file a.txt. I know that if the file has e.g. 6 lines, I can do:

for c in {1..6} ; do echo $c; done

which prints:

1
2
3
4
5
6

and I can count the number of lines as

wc -l a.txt | cut -f1 -d' '

which gives 2852

Now when trying to substitute the wc count into the for loop as follows, the loop doesn't work:

for c in {1..$(wc -l ~/a.txt| cut -f1 -d' ')} ; do echo $c; done

Instead of printing the numbers from 1 to 2852, it prints:

{1..2852}

How can I fix the sub-shell usage in the above loop to get the correct sequence of numbers?

( bash --version is (Debian):

GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.

)

tinlyx
  • 536
  • 1
  • 5
  • 22
  • 1
    See [How can I use $variable in a shell brace expansion of a sequence?](https://unix.stackexchange.com/questions/7738/how-can-i-use-variable-in-a-shell-brace-expansion-of-a-sequence) but more fundamentally [How to loop over the lines of a file?](https://unix.stackexchange.com/questions/7011/how-to-loop-over-the-lines-of-a-file) – steeldriver Mar 18 '23 at 02:27
  • If you use redirection `wc -l <~/a.txt` you get the count by itself and don't need `cut`. And if you only want to print the numbers you don't need a for loop, you can just run the `seq` program like `seq $(wc -l <~/a.txt)`. – dave_thompson_085 Mar 18 '23 at 04:38
  • @dave_thompson_085 Thanks a lot for the hints. – tinlyx Mar 18 '23 at 05:00

2 Answers2

1

Bash don't have feature to put a variable in brackets like

var=$(wc -l ~/a.txt| cut -f1 -d' ')}
echo {0..$var}

You can use a loop:

for ((i=0; i<var; i++)); do
    echo "$i"
done

Even if it's works, this should be avoided:

eval echo {0..$var}

eval is a common misspelling of 'evil'.
See http://mywiki.wooledge.org/BashFAQ/048

Gilles Quénot
  • 31,569
  • 7
  • 64
  • 82
1

You don't really need to know number of lines in a file to process it, just process it not even using a shell-loop; with awk:

awk '{ print "do something on line#", NR, $0 }' infile

in awk, the internal variable NR will return the Number of Record(/Line) and $0 is the content of that line which currently it is read for processing.

αғsнιη
  • 40,939
  • 15
  • 71
  • 114