grep "^$1"
amolyan művek, de hogyan menekülhetek "$1"
tehát a grep nem értelmezi külön a benne szereplő karaktereket?
Vagy van ennél jobb módszer?
Szerkesztés: Nem a "^$1"
-et akarom keresni, hanem egy dinamikusan beillesztett fix karakterláncot, amely csak illeszkedjen, ha egy sor elején van. Ezt értettem a $1
alatt.
Megjegyzések
Válasz
Nem tudok elképzelni egy módot ennek megvalósítására a grep
; önmagában a ^
használatával A reguláris kifejezés használatához a reguláris kifejezések értelmezése szükséges. Ez triviális a awk
, perl
vagy bármi másban:
awk -v search="$1" "substr($0, 1, length(search)) == search { print }"
Az \
-t tartalmazó keresési karakterláncok kezeléséhez ugyanazt a trükköt használhatja, mint a 123-as válasz :
search="$1" awk "substr($0, 1, length(ENVIRON["search"])) == ENVIRON["search"] { print }"
Megjegyzések
- Ez ‘ nem fog működni az ilyen karakterláncoknál mivel
\/
- @ 123 valóban, én ‘ hozzáadtam egy változatot ennek kezelésére.
- Továbbra is meg fog bukni olyan bonyolult karakterláncok esetében, mint például a
\\\/\/\/\\\\/
, amelyek\\///\\/
néven láthatók a programban. Tudomásom szerint nincs mód az awk visszavágások megfelelő elkerülésére, hacsak nem tudod, mennyit fognak felhasználni előzetesen. - @ 123 köszönöm, I ‘ a környezetben való átjutás trükkjét úgy alakítottuk át, hogy elkerüljük a menekülési folyamatokat.
- Még mindig ez a megoldás tetszik a legjobban. A hatékony (awk + nincs vesztegetett idő körülnézéssel), a gyors indítás (awk + nincs szükség további folyamatokra az állapot beállításához) szabványos eszközöket használ, és elég tömör. Az összes többi válaszból hiányzik ezek közül legalább néhány. (A hatékonyság itt erős pont, mivel a grep a páratlan sebességről ismert.)
Válasz
Ha csak ellenőrizni kell, hogy található-e egyezés vagy sem, az összes beviteli sort vágja le a kívánt előtag hosszára ($1
), majd használja a fix mintás grep-t:
if cut -c 1-"${#1}" | grep -qF "$1"; then echo "found" else echo "not found" fi
Könnyű megszerezni az egyező sorok számát is:
cut -c 1-"${#1}" | grep -cF "$1"
Vagy a minden egyező sor (a sorszámok 1-től kezdődnek):
cut -c 1-"${#1}" | grep -nF "$1" | cut -d : -f 1
A sorszámokat a head
és tail
az egyező sorok teljes szövegének megszerzéséhez, de ekkor könnyebb elérni egy olyan modern szkriptnyelvet, mint a Python vagy a Ruby.
(A fenti példák feltételezik, hogy a Posix grep és cut. Feltételezik, hogy a keresendő fájl szabványos bemenetről származik, de könnyen adaptálható fájlnév felvételére.)
Szerkesztés: Gondoskodnia kell arról is, hogy a minta ( $1
) nem nulla hosszúságú karakterlánc. Ellenkező esetben cut
nem sikerül kimondani a values may not include zero
szót. Ezenkívül a Bash használatakor használja a set -o pipefail
elemet a hibakibocsátások elkapásához cut
szerint.
Válasz
A perl használatával a visszavágásokat tiszteletben tartva
v="$1" perl -ne "print if index($_, $ENV{"v"} )==0" file
Ez beállítja a v környezeti változót parancsot, majd kinyomtatja, ha a változó indexe 0, azaz a sor eleje.
Ugyanezt megteheti az awk
v="$1" awk "index($0, ENVIRON["v"])==1" file
Válasz
Itt egy all-bash opció, nem az, hogy a bash-t javaslom a szövegfeldolgozáshoz, de működik.
#!/usr/bin/env bash # searches for $1 at the beginning of the line of its input len=${#1} while IFS= read -r line do [[ "${line:0:len}" = "$1" ]] && printf "%s\n" "$line" done
A szkript kiszámítja a hosszt A beírt $ 1 paraméter len
, majd az egyes sorok paraméterbővítésével megnézi, hogy az első len
karakterek megegyeznek-e a dollárral. Ha igen, akkor kinyomtatja a sort.
Válasz
Ha a $1
fájlja tiszta ASCII, és a A grep
rendelkezik a -P
opcióval (a PCRE engedélyezéséhez), ezt megteheti:
#!/bin/bash line_start="$1" line_start_raw=$(printf "%s" "$line_start" | od -v -t x1 -An) line_start_hex=$(printf "\\x%s" $line_start_raw) grep -P "^$line_start_hex"
Az ötlet az, hogy grep -P
lehetővé teszi a reguláris kifejezéseket \xXX
szó szerinti karakterek megadásához, ahol XX
az adott karakter hex ASCII értéke. Az er szó szerint illeszkedik, még akkor is, ha ez egyébként egy speciális regex karakter.
od
arra szolgál, hogy a várt sorkezdet hexa értékek listájává konvertálja, amelyek ezután összefűzik őket, mindegyiket a \x
előtaggal nyomtatja a printf. A ^
ezt a karakterláncot előkészíti a szükséges regex készítéséhez.
Ha a $1
unicode, akkor ez kissé nehezebbé válik, mert a karakterek 1: 1 arányban nem felelnek meg a hex bájtoknak od
kimeneteként.
Válasz
Ha a grep a -P opcióval rendelkezik, ami azt jelenti: PCRE , ezt megteheti:
grep -P "^\Q$1\E"
Lásd ezt a kérdést , és a részletekért lásd: PCRE doc , ha úgy tetszik.
Válasz
Szűrőként:
perl -ne "BEGIN {$pat = shift} print if /^\Q$pat/" search-pattern
Futtatás egy vagy több fájlon:
perl -ne "BEGIN {$pat = shift} print if /^\Q$pat/" search-pattern file..
A perlre dokumentáció „Metakarakterek idézése” szakasza elmagyarázza:
Idézés metakarakterek
Visszavágott metakarakterek a P-ben Az erl alfanumerikus, például:
\b
,\w
,\n
. Néhány más reguláris kifejezés nyelvétől eltérően nincsenek visszavágott szimbólumok, amelyek nem alfanumerikusak. Tehát minden, ami úgy néz ki, mint\\
,\(
,\)
, ,\]
,\{
vagy\}
szöveget mindig úgy értelmezik szó szerinti karakter, nem metakarakter. Ezt egyszer egy közös szóhasználatban használták a szabályos kifejezés metakaraktereinek speciális jelentéseinek letiltására vagy idézésére egy olyan karaktersorozatban, amelyet a mintához használni kívánt. Egyszerűen idézzen be minden nem „word” karaktert:$pattern =~ s/(\W)/\\$1/g;
(Ha a
use locale
be van állítva, akkor ez az aktuális területi beállítás.) Ma gyakoribb, ha aquotemeta
függvényt vagy a\Q
metaquoting menekülési szekvenciát használjuk az összes metakarakter speciális jelentésének letiltásához. így:/$unquoted\Q$quoted\E$unquoted/
Vigyázzon, hogy ha szó szerinti visszavágásokat (az interpolált változókon kívülieket)
\Q
és\E
, a dupla idézőjeles visszavágó interpoláció zavaros eredményekhez vezethet. Ha szó szerinti visszavonásokat kell használnia a\Q...\E
belül, olvassa el a “Az idézett konstrukciók elemzésének részletes adatai” című részt a perlopon .
quotemeta
és\Q
részletesen leírják az quotemeta .
Válasz
Ha van olyan karakter, amelyet nem ad “ne használja, ezzel jelölheti a sor elejét. Például $"\a"
(ASCII 007). Ez csúnya, de működni fog:
{ echo "this is a line to match"; echo "but this is not"; } >file.txt stuffing=$"\a" # Guaranteed never to appear in your source text required="this" # What we want to match that beginning of a line match=$(sed "s/^/$stuffing/" file.txt | grep -F "$stuffing$required" | sed "s/^$stuffing//") if [[ -n "$match" ]] then echo "Yay. We have a match: $match" fi
Ha nincs szüksége az egyező sor (ok) ra, akkor eldobhatja a záró sed
elemet és használhatja a grep -qF
. De ez sokkal könnyebb a awk
(vagy perl
) használatával …
Válasz
Ha hurok nélkül szeretne fájlba nézni, használhatja:
Vágja a fájlt a keresés hosszával karakterlánc
Rögzített karakterláncok és visszatérő sorok keresése
grep -Fn "$1" <(cut -c1-${#1} < file)
Használja a sorszámokat például sed -n "3p;11p" file
sed -n "$(grep -Fn "$1" <(cut -c1-${#1} < file) | sed "s/:.*/p;/" | tr -d "\n")" file
Ha törölni szeretné ezeket a sorokat, használja a
sed "$(grep -Fn "$1" <(cut -c1-${#1} < file) | sed "s/:.*/d;/" | tr -d "\n")" file
grep '^$1'
? Vagy nem ‘ t arra gondoltál, hogy meg akarod akadályozni, hogy a$1
kiterjedjen a héj?grep
kapcsolattal is, de ‘ Először el kell menekülnöd a karaktered bármelyik speciális karakterétől, pl.printf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile