Quiero grep para los archivos que contienen las palabras Dansk, Svenskao   Norsken cualquier línea, con un código de retorno utilizable (ya que realmente solo me gusta tener la información de que las cadenas están contenidas, mi línea única va un poco más allá de esto).
Tengo muchos archivos con líneas como esta:
Disc Title: unknown
Title: 01, Length: 01:33:37.000 Chapters: 33, Cells: 31, Audio streams: 04, Subpictures: 20
        Subtitle: 01, Language: ar - Arabic, Content: Undefined, Stream id: 0x20, 
        Subtitle: 02, Language: bg - Bulgarian, Content: Undefined, Stream id: 0x21, 
        Subtitle: 03, Language: cs - Czech, Content: Undefined, Stream id: 0x22, 
        Subtitle: 04, Language: da - Dansk, Content: Undefined, Stream id: 0x23, 
        Subtitle: 05, Language: de - Deutsch, Content: Undefined, Stream id: 0x24, 
(...)
Aquí está el pseudocódigo de lo que quiero:
for all files in directory;
 if file contains "Dansk" AND "Norsk" AND "Svenska" then
 then echo the filename
end
¿Cuál es la mejor manera de hacer esto? ¿Se puede hacer en una línea?

PIPESTATUSmatriz contiene los valores de salida de los miembros de una canalización.pipefailopción shell en (temporalmente):shopt -so pipefailgrep -Zyxargs -0si sus nombres de archivo pueden contener espacios.Otra forma más usando bash y grep:
Para un solo archivo 'test.txt':
Se imprimirá
test.txtsi el archivo contiene los tres (en cualquier combinación). Los dos primeros greps no imprimen nada (-q) y el último solo imprime el archivo si los otros dos han pasado.Si desea hacerlo para cada archivo del directorio:
fuente
for f ...: use"$f"(entre comillas dobles) en lugar de solo$fasegurarse de que los nombres de archivo con espacios incrustados, etc. se manejen correctamente.-ihace que la búsqueda no distinga entre mayúsculas y minúsculas-rhace que la búsqueda de archivos sea recursiva a través de carpetas-lcanaliza la lista de archivos con la palabra encontradacat -hace que el siguiente grep revise los archivos pasados a su lista.fuente
Cómo hacer grep para múltiples cadenas en un archivo en diferentes líneas (use el símbolo de tubería):
for file in *;do test $(grep -E 'Dansk|Norsk|Svenska' $file | wc -l) -ge 3 && echo $file doneNotas:
Si usa comillas dobles
""con su grep, tendrá que escapar de la tubería de esta manera:\|para buscar Dansk, Norsk y Svenska.Asume que una línea tiene un solo idioma.
Tutorial: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/
fuente
Norsk, pero en tres líneas diferentes.Puedes hacer esto muy fácilmente con ack :
ack -l 'cats' | ack -xl 'dogs'-l: devuelve una lista de archivos-x: toma los archivos de STDIN (la búsqueda anterior) y busca solo esos archivosY puede seguir canalizando hasta que obtenga solo los archivos que desea.
fuente
Unknown option: x. ¿Existe alguna versión de ack que admita esta bandera x?awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }'luego puede capturar el valor de retorno con el shell
si tienes Ruby (1.9+)
ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' filefuente
if (a && b && c) {exit 0} else {exit 1}o más lacónicamenteexit !(a && b && c)Esto busca varias palabras en varios archivos:
egrep 'abc|xyz' file1 file2 ..filenfuente
Simplemente:
grep 'word1\|word2\|word3' *ver esta publicación para más información
fuente
-lbandera, pero aparte de eso, esta respuesta me parece la más sencilla, a menos que me falte algo.Esta es una combinación de las respuestas de glenn jackman y kurumi que permite un número arbitrario de expresiones regulares en lugar de un número arbitrario de palabras fijas o un conjunto fijo de expresiones regulares.
#!/usr/bin/awk -f # by Dennis Williamson - 2011-01-25 BEGIN { for (i=ARGC-2; i>=1; i--) { patterns[ARGV[i]] = 0; delete ARGV[i]; } } { for (p in patterns) if ($0 ~ p) matches[p] = 1 # print # the matching line could be printed } END { for (p in patterns) { if (matches[p] != 1) exit 1 } }Ejecútelo así:
./multigrep.awk Dansk Norsk Svenska 'Language: .. - A.*c' dvdfile.datfuente
Esto es lo que funcionó bien para mí:
find . -path '*/.svn' -prune -o -type f -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \; ./path/to/file1.sh ./another/path/to/file2.txt ./blah/foo.phpSi solo quisiera encontrar archivos .sh con estos tres, entonces podría haber usado:
find . -path '*/.svn' -prune -o -type f -name "*.sh" -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \; ./path/to/file1.shfuente
Ampliando la respuesta awk de @ kurumi, aquí hay una función bash:
all_word_search() { gawk ' BEGIN { for (i=ARGC-2; i>=1; i--) { search_terms[ARGV[i]] = 0; ARGV[i] = ARGV[i+1]; delete ARGV[i+1]; } } { for (i=1;i<=NF; i++) if ($i in search_terms) search_terms[$1] = 1 } END { for (word in search_terms) if (search_terms[word] == 0) exit 1 } ' "$@" return $? }Uso:
if all_word_search Dansk Norsk Svenska filename; then echo "all words found" else echo "not all words found" fifuente
Hice eso con dos pasos. Haga una lista de archivos csv en un solo archivo Con la ayuda de los comentarios de esta página, hice dos pasos sin guiones para obtener lo que necesitaba. Simplemente escriba en la terminal:
$ find /csv/file/dir -name '*.csv' > csv_list.txt $ grep -q Svenska `cat csv_list.txt` && grep -q Norsk `cat csv_list.txt` && grep -l Dansk `cat csv_list.txt`Hizo exactamente lo que necesitaba: imprimir los nombres de los archivos que contienen las tres palabras.
También tenga en cuenta los símbolos como
`' "fuente
Si solo necesita dos términos de búsqueda, posiblemente el enfoque más legible es ejecutar cada búsqueda e intersecar los resultados:
fuente
Si tienes git instalado
--No-index busca archivos en el directorio actual que no está administrado por Git. Entonces, este comando funcionará en cualquier directorio, independientemente de si es un repositorio de git o no.
fuente
Tuve este problema hoy, y todas las frases ingeniosas aquí me fallaron porque los archivos contenían espacios en los nombres.
Esto es lo que se me ocurrió que funcionó:
grep -ril <WORD1> | sed 's/.*/"&"/' | xargs grep -il <WORD2>fuente