Revan
Revan

Reputation: 2322

Bash variable in for loop

I am sure this has been answered before, but I cannot find the solution.

for i in `ls | grep ^t`; do echo $i; done

This gives me the expected results (the files and directories starting with t). If I want to use a shell variable in the for loop (with the pipe), how do I do this? This was my start but it does not work.

z="ls | grep ^t"
for i in `$z` ; do echo $i; done

EDIT: I agree this example was not wisely chosen, but what I basically need ishow to use a variable (here $z) in the for loop (for i in $z) which has at least one pipe.

I try to state my question more clearly: How do I need to define my variable (if I want to loop over the output of a command with one or more pipes) and how is the call for the for loop?

Upvotes: 0

Views: 112

Answers (2)

Etan Reisner
Etan Reisner

Reputation: 80921

You don't use a variable for this. You don't put commands in strings. See Bash FAQ 050 for discussion about why.

You shouldn't be using a for loop to read data line-by-line anyway. See Bash FAR 001 for better ways to do that.

Specifically (though really read that page):

while IFS= read -r line; do
  printf '%s\n' "$line"
done < <(some command)

Upvotes: 0

riteshtch
riteshtch

Reputation: 8769

To loop through all files starting with t, you should use glob expansion instead of parsing ls output:

$ ls t*
tf  tfile
$ ls
abcd  tf  tfile
$ for i in t*; do echo "$i"; done
tf
tfile
$

Your approach will break in a number of cases, the simplest being when file names contain spaces. There is no need to use any external tool here; t* expands to all files starting with t.

As for your question, you use ls | grep ^t

And another good practice is to use subshell instead of backticks which are more readable and can be nested, use this: $(ls | grep ^t)

Upvotes: 4

Related Questions