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 aawk
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
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
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
.
-A
és-B
azonos.