2017-10-12 6 views
1
$ cat testfile 
first line mark apple 
second line not banana 
third line mark pear 

Je veux faire une boucle pour chaque ligne du fichier. S'il contient mark alors montrer la ligne entière sans perdre de place.Comment echo variable sans perdre de place dans une boucle for?

mais si mon code comme ci-dessous, il transforme l'espace en retour:

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

sortie est

first 
line 
mark 
apple 
third 
line 
mark 
pear 

si l'utilisation printf

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

sortie est

firstlinemarkapplethirdlinemarkpear 

comment puis-je obtenir la sortie comme ci-dessous:

first line mark apple 
third line mark pear 
+0

marque grep toto – xxfelixxx

+0

J'étais sur le point de suggérer 'pour i dans "$ (marque grep toto)"; fais écho "$ i"; done', mais il met 'I' $ à la totalité de la production de plusieurs lignes de la commande' grep' plutôt que itérer par des lignes. –

Répondre

2

Cela devrait être OK:

grep mark testfile 
2

Le plus simple est:

grep mark testfile 

Pas de boucle nécessaire. Et pas useless use of cat.


Mais si vous voulez comprendre pourquoi votre boucle ne fonctionne pas, il est parce que vous en boucle sur chaque mot dans la sortie de grep. Pour chaque boucle sur ligne vous devez utiliser read:

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

ou

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

En fait, pour être complètement sûr, il faut ajouter IFS= et read -r pour préserver tous les espaces et antislashs correctement.

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

Ceci est beaucoup de code inutile, cependant. Lis chaque ligne juste pour les cracher? Mieux vaut simplement omettre toute la boucle.

+0

C'est parfait. Mais en plus, après le grep, mon script doit boucler le résultat, et ramasser le dernier mot dans une fonction pour tester son motif, s'il est assorti, puis imprimer la ligne entière. Si tel est le cas que je devrais aller avec pour i dans la marque 'grep testfile'; faire? J'ai peur de cette façon, il se casse à nouveau? –

1

Merci à tous pour votre réponse, après conversion en fichier grep motif, le script est ci-dessous, laissez-moi savoir si c'est celui qui convient:

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 

ci-dessus tente de voir si « pattern » apparaissent dans une ligne de fichier, puis enlèvement du champ huitième comme ip, sixième champ comme FQDN (depuis la ligne est séparée par un espace); alors il vérifiera si $ ip est dans la portée de cidr par grepcidr, s'il n'est pas dans la portée (-v), puis vérifier si $ fqdn existe déjà dans le fichier fqdnfile, s'il n'est pas dans le fichier, alors écho fqdn dans ce fichier

Le fichier lui-même ressemble à ci-dessous:

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