Puncte:0

comanda echo întrerupe linii, fiind folosită în bucle

drapel br

În fișierul meu „foo” există o primă linie: „a b”, iar a doua linie: „c d”:

$ cat foo
a b 
c d

Vreau să printez în terminal în buclă aceste două linii: una după alta:

$ pentru i în $(cat foo); face eco $i; Terminat

Dar în ieșire comanda „echo” rupe ordinea, deci în loc să aibă:

a b
c d

De fapt am:

A
b
c
d
pLumo avatar
drapel in
`for i in $(cat foo)` nu bucla linii, ci cuvinte impartite de separatorul tau de camp (`IFS`).
drapel br
Deci, cum pot bucla linii / schimba modul IFS în buclă linii, nu cuvinte?
pLumo avatar
drapel in
Dacă ne spuneți ce doriți de fapt să faceți, vă putem ajuta să o faceți corect folosind „sed” sau cam așa ceva.,
Puncte:4
drapel in

pentru i în $(cat foo) nu buclă linii, ci cuvinte (sau câmpuri) împărțite de dvs separator de câmpuri $IFS. Implicit \n\t (spațiu, linie nouă, filă).

Dacă schimbați separatorul de câmpuri doar la linie nouă, puteți utiliza comanda așa cum este (Disclaimer: vă rugăm să citiți mai jos!):

IFS=$'\n'
pentru i în $(cat foo); face eco $i; Terminat

Poate doriți să faceți o copie de rezervă a IFS pentru a-l restaura mai târziu:

OLD_IFS="$IFS"
.
.
.
IFS="$OLD_IFS"

Ieșire:

a b
c d

Cu toate acestea, acest lucru este luat în considerare rău practică.

  • Puțin mai bine: în timp ce IFS= citește linia -r; do ... done < fișier
  • Mult mai bine: utilizați un instrument dedicat sarcinii dvs., cum ar fi grep, sed sau awk.

Vă rog să citiți De ce utilizarea unei bucle shell pentru a procesa text este considerată o practică proastă?.

drapel br
Cum pot folosi „grep” în schimb?
pLumo avatar
drapel in
Nu putem ști, pentru că nu știm ce vrei să faci, vezi ultimul meu comentariu la întrebarea ta.
Puncte:2
drapel ph

Poți să folosești în timp ce se citește în acest scop

[/tmp]$ în timp ce linia de citire ; do echo $line ; facut < foo                                     
a b
c d

Adăugarea unui separator pentru înțelegerea dvs

[/tmp]$ în timp ce linia de citire ; do echo $line ; ecou "----" ; facut < foo                       
a b
----
c d
----
[/tmp]$    
drapel br
Dacă vreau să merg cu soluția ta, dar și să adaug o declarație condiționată în bucla mea for, atunci care va fi „$i”? Adică, ceva de genul acesta: pentru i în $(în timp ce citește linia; do echo $linia; terminat
drapel hr
Rețineți că `$line` ar trebui să fie citat `"$line"` din motive similare (în caz contrar, cuvântul va fi împărțit în simboluri separate - încercați cu `a b` în loc de `a b`, de exemplu).
drapel hr
... de asemenea, `read` ar elimina în continuare orice spațiu alb de început și va extinde secvențele de evadare în mod implicit, așa că, mai general, dacă doriți să ecou liniile *exact*, ați dori `while IFS= citiți linia -r; do ...` sau (pentru a include o eventuală ultima linie terminată incorect) `while IFS= read -r line || [[ -n „$line” ]]; face...`
bac0n avatar
drapel cn
@JosefKlimuk ```în timp ce citește -r; fă dacă! grep -oe 'a'

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.