Bright Zhao
Bright Zhao

Reputation: 97

How to echo variable without losing space in a for loop?

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

I want to for loop each line of the file. If it contains mark then show the whole line without losing space.

but if my code as below, it turns the space into return:

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

output is

first
line
mark
apple
third
line
mark
pear

if use printf

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

output is

firstlinemarkapplethirdlinemarkpear

how can I get the output as below:

first line mark apple
third line mark pear

Upvotes: 1

Views: 416

Answers (3)

Bright Zhao
Bright Zhao

Reputation: 97

Thank you all for your reply, after convert into grep pattern file, the script is below, let me know if it's the appropriate one:

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

The above is trying see if 'pattern' show up in any line of file, then it pick-up the eighth field as ip, sixth field as fqdn(since the line is separated by space); then it will check whether $ip is in the cidr scope by grepcidr, if it's not within the scope(-v), then to check whether the $fqdn already exist in fqdnfile file, if it's not in the file, then echo the $fqdn into that file

The file itself looks like below:

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

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361635

The easiest way is:

grep mark testfile

No loop needed. And no useless use of cat.


But if you want to understand why your loop doesn't work, it's because you're looping over each word in grep's output. To loop over each line you need to use read:

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

or

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

Actually, to be completely safe, we should add IFS= and read -r to preserve all whitespace and backslashes properly.

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

This is a lot of unnecessary code, though. Reading each line just to spit them back out? Better to just omit the whole loop.

Upvotes: 2

Krassi Em
Krassi Em

Reputation: 192

This should be OK:

grep mark testfile

Upvotes: 2

Related Questions