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
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
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 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 (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
grep '^$1'
? Vagy nem ‘ t arra gondolt, hogy meg akarja akadályozni, hogy a$1
kiterjedjen a héj?grep
használatával is, de ‘ Először el kell kerülnöd a karaktered bármely speciális karakterét, plprintf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile