Efter råd under denna fråga kan jag rekursivt grep för en sträng string
i innehållet i en viss katalog dir
enligt följande
grep -r --exclude-dir=".*" string dir
När jag tillämpar detta på den aktuella katalogen, som
$ grep -r --exclude-dir=".*" string . $
, får jag inga resultat eftersom --exclude-dir=".*"
alternativet utelämnar den aktuella katalogen som dold eftersom den matchar ".*"
.
En lösning är att byta till överordnad katalog via cd ..
, kör sedan kommandot på lämpligt barn och sedan cd
tillbaka till den ursprungliga arbetskatalogen. Det måste finnas ett enda kommando som jag kan använda för att göra detta utan att kringgå att ändra kataloger.
Vad är ett enda kommando för att grep innehåll i den aktuella katalogen, utelämnar innehållet i dolda kataloger?
Svar
Om du använder GNU grep 2.11 eller senare startar -r
från den aktuella katalogen om ingen katalog är angiven:
grep -r --exclude-dir=".*" string
Kommentarer
Svar
I shell glob (även känt som filnamnmönster) har .
ingen speciell betydelse, *
betyder noll eller fler tecken och ?
betyder varje enskilt tecken.
Vad du vill utesluta är en punkt följt av minst en tecken och sedan valfritt antal tecken. Så använd:
grep -r --exclude-dir=".?*" string .
Svar
Eftersom bash
vann ”t har grep
korsar dolda kataloger som standard (dvs utan dotglob
aktiverat:
$ tree -a . ├── .test │ ├── .file │ └── file ├── file └── test ├── .file └── file 2 directories, 5 files $ grep -r foo * file:foo test/.file:foo test/file:foo
Uteslut bara dolda filer:
$ grep --exclude=".*" -r foo * file:foo test/file:foo
Kommentarer
- Jag är nyfiken på resonemanget bakom den icke kommenterade nedröstningen.
- Jag gjorde inte ' t downvote, men det ' är inte sant att
grep
inte ' inte korsar dolda kataloger. Vad du ' ser igen medgrep -r foo *
är att skalet glob*
inte ' t expandera för att inkludera dolda kataloger / filer, om intedotglob
har ställts in medshopt -s dotglob
.grep -r foo .
och du ' Se att de dolda katalogerna korsas av grep. Eller försök medshopt -s dotglob
och sedangrep -r foo *
. - Fair point; Jag har förtydligat detta i mitt svar.
- Detta kommer fortfarande att söka efter filer i dolda kataloger som finns i kommandoradsargumenten. Det kommer att fungera. I de flesta fall kan det vara okej, men det ' är som att definiera " pi " som " 3.1416 "; du känner bättre till försiktigheten.
Svar
Du kan också ange aktuell katalog med $(pwd)
som:
grep -r --exclude-dir=".*" string "$(pwd)"
Kommentarer
- Citera ditt kommandosubstitution:
"$(pwd)"
Se även Varför kväver mitt skalskript i mellanslag eller andra specialtecken?
Svar
För att återställa i en singel katalog (begränsar inte dolda filer i underkataloger) använder:
Eftersom echo dir/*
kommer att skriva ut alla filer i dir, kommer detta att fungera för filer i vissa dir:
$ grep -r "string" $(echo dir/*)
ändra bara dir
till .
(punkt) och du får exakt vad du vill:
$ grep -r "string" $(echo ./*)
Om det som behövs inte finns några dolda filer i någon av underkatalogerna, använd antingen:
$ grep -r --exclude-dir=".*" "string"
Eller använd sök:
find . -not -path "*/\.*" -type f -exec grep "string" {} \+
grep
producerar det:grep: warning: recursive search of stdin