3

我在多个子目录中有文本文件

一些/路径/一个/文件

一些/路径/两个/文件

一些/路径/三个/文件

一些/路径/foo/文件

...

我需要能够 grep 文件进行匹配,但保留单独的行返回,以便以后可以使用循环单独操作每个匹配。

我有:

SITE=$(grep -w $1 some/path/*/file)

然而,这只会产生一个非常长的字符串,所有内容都只是在一行中平滑在一起。

理想情况下,此变量将包含每行路径名中 * 的值:

例如:

一些/路径/一个/文件

一些/路径/三个/文件

包含其中包含的行bar

SITE=$(grep -w bar some/path/*/file)
echo $SITE

应该是这样的:

some/path/one/file:this is a line of text that has bar in it
some/path/three/file:this is a line of text that has bar in it

但相反,我得到了这个:

some/path/one/file:this is a line of text that has bar in it some/path/three/file:this is a line of text that has bar in it

有没有办法让这个变量多行,以便以后我可以做类似的事情:

for i in `echo $SITE`; do
WHATEVER=$(echo $i | cut -d ':' -f 1 | cut -d '/' -f 3)
echo $WHATEVER
done

并使输出为:

one
three

或者我会以完全错误的方式解决这个问题?

4

3 回答 3

3

不是$()命令替换将输出简化为一行。它是echo一个未引用的变量。如果你这样做echo "$SITE",你会看到多行输出。

话虽如此,逐行阅读的常用方法是while read构造。你可以这样做:

while read line; do
    WHATEVER=$(echo "$i" | cut -d ':' -f 1 | cut -d '/' -f 3)
    echo $WHATEVER
done < <(grep -w bar some/path/*/file)

请注意,我们可以在最后一行使用管道代替<()进程替换,但是如果在 while 循环中设置的变量需要保留在 while 循环之外的范围内,则上述方法会更好。

当然,如果这就是你需要对输出做的所有事情,那么下面的内容就简单多了:

grep -w bar some/path/*/file | cut -d ':' -f 1 | cut -d '/' -f 3
于 2014-03-14T20:08:56.927 回答
0

IFS=$'\r\n' LINES=($(grep -w $1 some/path/*/file))

这将创建一个行数组

然后,您可以遍历数组并单独处理每一行${LINES[i]}

在此处查看更多信息https://stackoverflow.com/a/11393884/652904

于 2014-03-14T20:18:17.933 回答
0

如果只是为了显示,总是有echo -e "$SITE". 该-e选项保留所有制表符、空格和换行符。不要忘记引号。

如果您想稍后在脚本中处理每一行,您可以尝试以下操作:

echo -n "$SITE" | while read line ; do
  echo "$line"
done
于 2014-03-14T20:06:50.543 回答