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 illeszkedni kell, ha egy sor elején van. Ezt értettem a $1 alatt.

Megjegyzések

  • Megpróbáltál egyetlen idézetet használni kettős idézőjel helyett, pl grep '^$1'? Vagy nem ‘ t arra gondolt, hogy meg akarja akadályozni, hogy a $1 kiterjedjen a héj?
  • @mnille Nem ‘ nem a ‘ ^ $ 1 ‘, hanem egy dinamikusan beillesztett szót akarom keresni fix karakterlánc, amely csak akkor illeszthető össze, ha ‘ s van a sor elején. Ezt ‘ értem az 1 dollár alatt.
  • Megteheti a grep használatával is, de ‘ Először el kell kerülnöd a karaktered bármely speciális karakterét, pl printf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile
  • @don_crissti, amely ‘ jobb, mint a többi válasz. Nem törődik azzal, hogy eggyé váljon?
  • @roaima – tudom, de ‘ itt már egy csomó válasz van, és ez (a vars-okon belüli különleges karakterek elől elkerülve) amit én (és még néhány más felhasználó itt) jó ideje kalapálok hazafelé … Mindig hozzáadhatja a válaszához, ha akarja, és ‘ eltávolítom a írjon ide (ne ‘ ne felejtse el hozzáadni a hiányzó vezető zárójelet).

Válasz

Nem tudok elképzelni ennek módját a grep használatával; maga a ^ egy a reguláris kifejezés, ezért használatához a reguláris kifejezések értelmezése szükséges. Ez triviális a (z) awk, perl vagy bármi másban: p>

awk -v search="$1" "substr($0, 1, length(search)) == search { print }" 

A \ -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 sikerült az ilyen karakterláncok számára 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 meglehetősen 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, vágjon minden bemeneti sort 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 bemenetből származik, de könnyen adaptálható fájlnévre.)

Szerkesztés: Gondoskodnia kell arról is, hogy a minta ( $1) nem nulla hosszúságú karakterlánc. Egyébként cut nem sikerül kimondani az values may not include zero szót. Ezenkívül a Bash használatakor használja a set -o pipefail parancsot a hibakimenetek befogására 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 a 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

fájlban is

Itt egy all-bash opció, nem azért, mert a szöveg feldolgozásához a bash-t javaslom, 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 megvizsgálja, hogy az első len karakterek megegyeznek-e az 1 dollárral. Ha igen, akkor kinyomtatja a sort.

Válasz

Ha a $1 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 a grep -P rendszeres kifejezéseket enged meg \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, és mindegyiket a \x elé írja 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-nél van a -P opció, 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 megmagyará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 bármi, ami úgy néz ki, mint \\, \(, \), \[, \], \{ vagy \} mindig úgy értelmezzük, hogy szó szerinti karakter, nem metakarakter. Ezt egyszer egy közös szóhasználatban alkalmazták a reguláris 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 a quotemeta 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 (azokat, amelyek nem az interpolált változók belsejében vannak) \Q és A \E 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 a quotemeta .

Válasz

Ha van olyan karakter, amelyet nem ad “ne használja, ezt használhatja a sor elejének megjelölésére. Például $"\a" (ASCII 007). 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éged az egyező sor (ok) ra, akkor eldobhatod a záró sed elemet és használhatod a grep -qF. De a awk (vagy perl) használatával sokkal könnyebb …

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 

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