¿Cómo contaría cada aparición de un término en todos los archivos en el directorio actual? - y subdirectorios (?)
He leído que para hacer esto usarías grep
; ¿Cuál es el comando exacto?
Además, ¿es posible lo anterior con algún otro comando?
¿Cómo contaría cada aparición de un término en todos los archivos en el directorio actual? - y subdirectorios (?)
He leído que para hacer esto usarías grep
; ¿Cuál es el comando exacto?
Además, ¿es posible lo anterior con algún otro comando?
Respuestas:
Usando grep
+ wc
(esto atenderá múltiples ocurrencias del término en la misma línea):
grep -rFo foo | wc -l
-r
in grep
: busca recursivamente en la jerarquía de directorios actual;-F
in grep
: coincide con una cadena fija en lugar de con un patrón;-o
en grep
: imprime solo coincidencias;-l
en wc
: imprime el recuento de las líneas;% tree
.
├── dir
│ └── file2
└── file1
1 directory, 2 files
% cat file1
line1 foo foo
line2 foo
line3 foo
% cat dir/file2
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8
PCREs
debería usarse ya que son experimentales
-F
probablemente sería más rápido.
-F
lugar de -P
. Gracias por la gran sugerencia, la actualización usando -F
, que de hecho encaja mejor aquí.
grep -Rc [term] *
lo haré. El -R
indicador significa que desea buscar de forma recursiva el directorio actual y todos sus subdirectorios. El *
es un selector de archivos que significa: todos los archivos. La -c
bandera hace que la grep
salida solo sea el número de ocurrencias. Sin embargo, si la palabra aparece varias veces en una sola línea, solo se cuenta una vez.
De man grep
:
-r, --recursive
Read all files under each directory, recursively, following symbolic links only if they are on the command line.
This is equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
Si no tiene enlaces simbólicos en su directorio, no hay diferencia.
-c
bandera a grep
. Entonces grep cuenta y no necesitas elwc
--
antes*
*
única ampliará a los no comienzan con un punto, por lo que se le pasa a todos aquellos. Tiene más sentido simplemente usar "." ya que de todos modos va a procesar argumentos de forma recursiva, y eso obtendrá archivos de puntos. El mayor problema aquí es que esto podría ser el número de líneas, no el número de apariciones de una palabra. Si el término aparece varias veces en una línea, solo se contará una vez por "grep -c"
En un pequeño script de Python:
#!/usr/bin/env python3
import os
import sys
s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
for f in files:
f = root+"/"+f
try:
n = n + open(f).read().count(s)
except:
pass
print(n)
count_string.py
.Ejecútelo desde el directorio con el comando:
python3 /path/to/count_string.py <term>
# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
for f in files:
# join the path(s) above the file and the file itself
f = root+"/"+f
# try to read the file (will fail if the file is unreadable for some reason)
try:
# add the number of found occurrences of <term> in the file
n = n + open(f).read().count(s)
except:
pass
print(n)
root
y f
para qué?
root
es la ruta al archivo que incluye "arriba" del directorio actual, f
es el archivo. Alternativamente, os.path.join()
podría usarse, pero es más detallado.
n = n + open(f).read().count(s)
?