Az alábbiakban található a fájl szövege:

Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good 

Grepelni kell “42B”, és kapja meg a fenti szöveg kimenetét, például:

Pseudo name=Apple Code=42B state=fault 

Van valakinek ötlete, hogyan lehet ezt elérni a grep / awk / sed?

Megjegyzések

  • Ezt a kérdést csak " grep " címkével látta el. Akkor csak a " grep " megoldásokat keresi? A kérdésben megadja az awk & sed szót is. Hozzáadhatjuk ezeket a címkéket? Nem voltam biztos a szándékodban, amikor tegnap este szerkesztettem a kérdést.
  • stackoverflow.com/ kérdések / 12024410 / …

Válasz

A következővel: awk

awk -v RS="" "/42B/" file 

RS= megváltoztatja a bemeneti rekord elválasztóját új sortól az üres sorokig. Ha a rekord bármely mezője tartalmaz /42B/ nyomtatást, nyomtassa ki a rekordot.

"" (a null karakterlánc) varázslat az üres sorok ábrázolására használt érték a POSIX szerint:

Ha RS semleges, akkor a rekordokat szétválasztják egy <newline> plusz egy vagy több üres szekvenciával a vonalak, az üres vagy a záró sorok nem eredményezhetnek üres rekordokat a bemenet elején vagy végén, és a <newline> mindig mezőelválasztónak kell lennie, függetlenül a FS is.

A kimeneti bekezdések nem elválasztani, mivel a kimeneti elválasztó egyetlen új vonal marad. Annak biztosítása érdekében, hogy a kimeneti bekezdések között üres sor legyen, állítsa a kimeneti rekord elválasztót két új sorra:

awk -v RS="" -v ORS="\n\n" "/42B/" file 

megjegyzések

  • +1 az elegáns megoldásért. Nem kell azonban ' átirányítani a fájlt …
  • az ujjak autopilótán voltak.
  • @jasonwryan, hacsak nincs szükséged hozzáférésre az awk fájlnévhez (FILENAME), ' nem rossz ötlet az átirányítást használni, mivel így elkerülhetők a = vagy - -vel kezdődő (vagy - -es) következetes hibaüzeneteket eredményez, és kerüli a awk futtatását vagy más átirányítások végrehajtását, ha a bemeneti fájl ' nem nyitható meg.

Válasz

Feltéve, hogy az adatok úgy vannak strukturálva, hogy mindig az előtte és utána kívánt sor legyen, használhatja a grep s -A (utána) és -B (előtte) kapcsolók azt mondják, hogy a meccs előtti 1 sort és az utána egy sort tartalmazza:

$ grep -A 1 -B 1 "42B" sample.txt Pseudo name=Apple Code=42B state=fault 

Ha a ugyanazon a soron a keresési kifejezés előtt és után használhatja a -C (context) kapcsolót:

$ grep -C 1 "42B" sample.txt Pseudo name=Apple Code=42B state=fault 

Ha szigorúbbnak akar lenni, ha több sort illeszt, használhatja a pcregrep eszközt a mintázat több vonalon:

$ pcregrep -M "Pseudo.*\n.*42B.*\nstate.*" sample.txt Pseudo name=Apple Code=42B state=fault 

A fenti minta a következőképpen illeszkedik:

  • -M – több sor
  • "Pseudo.*\n.*42B.*\nstate.*" – egy olyan húrcsoportra illeszkedik, ahol az első karakterlánc a "Pseudo", amelyet a karakterek követnek a \n sor végéig, majd bármely karaktert a "42B" karakterláncig, majd bármely karaktert a sor másik vége (\n), amelyet a "state" karakterlánc követ, majd bármely karaktert.

Megjegyzések

  • (context) parancsikonként használható, ha -A és -B azonos.
  • @DavidBaggerman – köszönöm. Hozzáadta a válaszhoz.
  • Miért pont az egy leszavazás? Ez megválaszolja a kérdést.

Válasz

A grep a Unix egyes ízei a -p zászlóval rendelkeznek a “bekezdés” kifejezéshez. Tudom, hogy a AIX nem .

grep -p 42B <myfile> 

pontosan azt csinálná, amit ott kérsz . Az YMMV és a GNU grep nem rendelkezik ezzel a zászlóval.

Megjegyzések

  • A -p jelző csodálatos lenne. Különösen, ha -v-vel együtt használjuk, így a teljes bekezdések kizárhatók a kimenetből.

Válasz

Valószínűleg hasonlóan egyszerű módja van az awk-nak, de a perl-ben:

cat file | perl -ne "BEGIN { $/="\n\n" }; print if $_ =~ /42B/;" 

Ez alapvetően azt mondja, hogy a fájlt üres sorokkal határolt darabokra kell felosztani, majd csak azokat a darabokat kell kinyomtatni, amelyek megfelelnek a reguláris kifejezésnek.

Megjegyzések

  • Ez egyszerűsíthető opciók és rövidítések használatával, és elveszíti a ; perl -00 -ne 'print if /42B/' file

Válasz

Más perl megoldás, anélkül üres sor zárása:

perl -00ne "if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}" foo 

Példa

% perl -00ne "if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}" foo Pseudo name=Apple Code=42B state=fault % cat foo Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good 

Megjegyzések

  • Vagy rövidebbek (és így olvashatóbbak), ahogy triplee írta egy megjegyzésben: perl -00 -ne 'print if /42B/' file.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük