简体   繁体   English

Bash变量在for循环中

[英]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). 这给了我预期的结果(以t开头的文件和目录)。 If I want to use a shell variable in the for loop (with the pipe), how do I do this? 如果我想在for循环(使用管道)中使用shell变量,该怎么做? 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. 编辑:我同意这个例子不是明智的选择,但是我基本上需要的是如何在for循环( for i in $z )中使用一个变量(这里$z ),该变量至少有一个管道。

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? 我尝试更清楚地陈述我的问题:如何定义变量(如果我想使用一个或多个管道来循环命令的输出)以及for循环的调用是什么?

To loop through all files starting with t , you should use glob expansion instead of parsing ls output: 要遍历所有以t开头的文件,您应该使用glob扩展而不是解析ls输出:

$ 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. t *扩展到以t开头的所有文件。

As for your question, you use ls | grep ^t 至于您的问题,请使用ls | grep ^t 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) 另一个好的做法是使用subshel​​l而不是反引号,反引号更易读并且可以嵌套,请使用以下命令: $(ls | grep ^t)

You don't use a variable for this. 您无需为此使用变量。 You don't put commands in strings. 您不要将命令放在字符串中。 See Bash FAQ 050 for discussion about why. 有关原因的讨论,请参见Bash FAQ 050

You shouldn't be using a for loop to read data line-by-line anyway. 无论如何,您都不应该使用for循环逐行读取数据。 See Bash FAR 001 for better ways to do that. 有关更好的方法,请参见Bash FAR 001

Specifically (though really read that page): 具体来说(尽管确实读过该页面):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM