Problema este că grep
va rula pe fiecare linie, nu pe întregul fișier. Atâta timp cât fișierul este suficient de mic pentru a se potrivi în memorie (ceea ce ar trebui să fie cazul în marea majoritate a situațiilor din zilele noastre), puteți folosi grep -z
flag pentru a slurp întregul fișier:
-z, --null-data
Tratați datele de intrare și de ieșire ca secvențe de
linii, fiecare terminată cu un octet zero (ASCII NUL
caracter) în loc de o nouă linie. Ca și opțiunea -Z sau --null, această opțiune poate fi folosită cu comenzi
precum sort -z pentru a procesa nume de fișiere arbitrare.
Următoarea problemă, este că dacă treci grep
ceva cu linii noi, îl va trata ca pe o listă de modele pentru care să se grepească:
$ string="1
> 2"
$ secv 10 | grep "$șir"
1
2
10
"
Ceea ce înseamnă că mă tem că va trebui să exprimi modelul ca o expresie regulată adecvată:
\n\ntest1\n\ntest2\n\n
Cu toate acestea, acest lucru înseamnă și că aveți nevoie de -P
flag pentru a activa expresiile regulate compatibile cu perl, astfel încât \n
va functiona.
Am creat aceste două fișiere pentru a demonstra:
$ fisier pisica1
acesta este un test:
test1
testul2
si inca una
$ fisier pisica2
acesta este un test:
test1
testul2
si inca una
Folosind aceste două fișiere și informațiile de mai sus, puteți face:
$ grep -Pz „\n\ntest1\n\ntest2\n\n” fișier1
$
$ grep -Pz „\n\ntest1\n\ntest2\n\n” fișier2
acesta este un test:
test1
testul2
si inca una
Punând toate acestea împreună, ne dă:
șir='\n\ntest1\n\ntest2\n\n'
dacă ! grep -Pzq "$șir" test.txt; atunci
printf "$șir" >> test.txt
fi
Sau, așa cum sugerează @steeldriver într-un comentariu, puteți utiliza o variabilă și puteți converti liniile noi în \n
pe fuga:
$ string="
test1
testul2
"
$ daca ! grep -Pzq "${string//$'\n'/\n}" test.txt; atunci
printf "$șir" >> test.txt
fi
Dacă șirul dvs. conține caractere speciale care au semnificații în expresiile regulate, așa cum arătați acum în întrebarea dvs. actualizată, atunci aceasta este o situație complet diferită. Pentru exemplul pe care îl arăți, ai avea nevoie de ceva mult mai complicat. Ca aceasta:
searchString='\n\nif \[ -f ~/.script \]; apoi\s*\n\s*\.\s+~/\.script\s*\nfi\n\n'
printString='
if [ -f ~/.script ]; atunci
. ~/.script
fi
'
dacă ! grep -Pzq "$searchString" test.txt; atunci
printf „%s” „$printString” >> test.txt
fi