如何在for循环中回送变量而不丢失空间?

时间:2017-10-12 00:11:40

标签: bash shell for-loop echo

$ cat testfile
first line mark apple
second line not banana
third line mark pear

我想循环文件的每一行。如果它包含mark,则显示整行而不会丢失空格。

但是如果我的代码如下所示,它会将空格变为返回:

for i in `cat testfile | grep mark`; do
    echo $i
done

输出

first
line
mark
apple
third
line
mark
pear

如果使用printf

for i in `cat testfile | grep mark`; do
    printf $i
done

输出

firstlinemarkapplethirdlinemarkpear

如何获得如下输出:

first line mark apple
third line mark pear

3 个答案:

答案 0 :(得分:2)

这应该没问题:

grep mark testfile

答案 1 :(得分:2)

最简单的方法是:

grep mark testfile

不需要循环。没有useless use of cat

但是如果你想了解为什么你的循环不起作用,那是因为你在grep的输出中循环遍历每个单词。要遍历每个,您需要使用read

cat testfile | grep mark | while read line; do
    echo "$line"
done

while read line; do
    echo "$line"
done <(cat testfile | grep mark)

实际上,为了完全安全,我们应该添加IFS=read -r来正确保留所有空格和反斜杠。

cat testfile | grep mark | while IFS= read -r line; do
    echo "$line"
done

但这是很多不必要的代码。阅读每一行只是为了吐出来?最好省略整个循环。

答案 2 :(得分:1)

感谢大家的回复,转换成grep模式文件后,脚本如下:请告诉我是否合适:

grep pattern file | while read line; do
    ip=`echo $line | cut -d ' ' -f 8`
    fqdn=`echo $line | cut -d ' ' -f 6`
    grepcidr -v -f /root/collect/china_routes.txt <(echo $ip) >/dev/null
    if [ $? == 0 ]; then
        grep $fqdn fqdnfile || echo $fqdn >> /root/collect/fqdn
    fi
done

以上是试图看看'pattern'是否出现在任何文件行中,然后它将第八个字段作为ip,第六个字段作为fqdn(由于该行以空格分隔);那么它将检查$ ip是否在greidcidr的cidr范围内,如果它不在范围内(-v),那么检查fqdn文件中是否已存在$ fqdn,如果它不在文件中,则回显$ fqdn进入该文件

文件本身如下所示:

Oct 11 20:19:05 dnsmasq[30593]: reply api.weibo.com is 180.149.135.176
Oct 11 20:19:05 dnsmasq[30593]: reply api.weibo.com is 180.149.135.230
Oct 11 20:19:06 dnsmasq[30593]: query[A] sina.com from 180.169.158.178
Oct 11 20:19:06 dnsmasq[30593]: forwarded sina.com to 114.114.114.114
Oct 11 20:19:06 dnsmasq[30593]: reply sina.com is 66.102.251.33
Oct 11 20:19:06 dnsmasq[30593]: query[PTR] 74.103.225.116.in-addr.arpa from 127.0.0.1
Oct 11 20:19:06 dnsmasq[30593]: cached 116.225.103.74 is NXDOMAIN-IPv4