Tengo los siguientes archivos:
Codigo-0275_tdim.matches.tsv
Codigo-0275_tdim.snps.tsv
FloragenexTdim_haplotypes_SNp3filter17_single.tsv
FloragenexTdim_haplotypes_SNp3filter17.tsv
FloragenexTdim_SNP3Filter17.fas
S134_tdim.alleles.tsv
S134_tdim.snps.tsv
S134_tdim.tags.tsv
Quiero contar el número de archivos que tienen la palabra snp
(mayúsculas y minúsculas) en su nombre. Traté de usar
grep -a 'snp' | wc -l
pero luego me di cuenta de que grep
busca dentro de los archivos. ¿Cuál es el comando correcto para escanear los nombres de archivo?
Respuestas:
¿Quiere decir que desea buscar
snp
en los nombres de archivo ? Eso sería un simple shell glob (comodín), usado así:Omita la
-q
bandera si su versión dels
no la reconoce. Maneja nombres de archivo que contienen caracteres "extraños" (incluidas las nuevas líneas).fuente
ls
para recuperar nombres de archivo con texto específico en ellos. Eso funcionó, gracias.ls
es que coincida con los nombres de los archivos, es el shell.ls
ve una lista de archivos que coinciden con el patrón; sí no ver el patrón en sí.Si te quedas en silencio en los pasillos de Unix y Linux y escuchas con atención, escucharás una voz fantasmal, lamentando, "¿Qué pasa con los nombres de archivo que contienen nuevas líneas?"
o, equivalentemente ,
generará todos los nombres de archivo que contienen
snp
, cada uno seguido de una nueva línea, pero también incluirá cualquier nueva línea en los nombres de archivo , y luego contará el número de líneas en la salida. Si hay un archivo cuyo nombre esf o o s n p \n b a r . t s v
entonces ese nombre se escribirá como
que, por supuesto, se contarán como dos líneas.
Hay algunas alternativas que funcionan mejor en al menos algunos casos:
que cuenta las líneas que contienen
snp
, por lo que elfoosnp(\n)bar.tsv
ejemplo anterior solo cuenta una vez. Una ligera variación en esto esLos dos comandos anteriores difieren en que:
ls -f
incluirá archivos cuyos nombres comienzan con.
; elprintf … *
no lo hace, a menos que ladotglob
opción del shell se establece.printf
es una concha incorporada;ls
Es un comando externo. Por lo tanto,ls
podrían usar un poco más de recursos.*
, ordena los nombres de archivo;ls -f
no ordena los nombres de archivo. Por lo tanto,ls
podrían usar un poco menos de recursos.Pero tienen algo en común: ambos darán resultados incorrectos en presencia de nombres de archivo que contienen nueva línea y tienen
snp
tanto antes como después de la nueva línea .Otro:
Esto crea una variable de matriz de shell que enumera todos los nombres de archivo que contienen
snp
, y luego informa el número de elementos en la matriz. Los nombres de archivo se tratan como cadenas, no como líneas, por lo que las nuevas líneas incrustadas no son un problema. Es concebible que este enfoque pueda tener un problema si el directorio es enorme, porque la lista de nombres de archivo debe mantenerse en la memoria de shell.Aún otra:
Anteriormente, cuando dijimos
printf "%s\n" *snp*
, elprintf
comando repitió (reutilizó) la"%s\n"
cadena de formato una vez para cada argumento en la expansión de*snp*
. Aquí, hacemos un pequeño cambio en eso:Esto repetirá (reutilizará) la
"%.0s\n"
cadena de formato una vez para cada argumento en la expansión de*snp*
. Pero"%.0s"
significa imprimir los primeros cero caracteres de cada cadena, es decir, nada. Esteprintf
comando generará solo una nueva línea (es decir, una línea en blanco) para cada archivo que contengasnp
su nombre; y luegowc -l
los contaré. Y, nuevamente, puede incluir los.
archivos configurandodotglob
.fuente
Abstracto:
Funciona para archivos con nombres "impares" (incluidas nuevas líneas).
Descripción
Como un globo simple coincidirá con cada nombre de archivo
snp
en su nombre, un simpleecho *snp*
podría ser suficiente para este caso, pero para mostrar realmente que solo hay tres archivos coincidentes, usaré:El único problema que queda es contar los archivos. Sí, grep es una solución habitual, y sí, contar nuevas líneas
wc -l
también es una solución habitual. Tenga en cuenta quegrep -c
(recuento) realmente cuenta cuántas vecessnp
coincide una cadena y, si un nombre de archivo tiene más de unasnp
cadena en el nombre, el recuento será incorrecto.Podemos hacerlo mejor.
Una solución simple es establecer los argumentos posicionales:
Para evitar cambiar los argumentos posicionales, podemos transformar cada argumento en un carácter e imprimir la longitud de la cadena resultante (para la mayoría de los shells):
O, en bash, para evitar una subshell:
Lista de archivos
Lista de archivos (de la pregunta original con una con una nueva línea agregada):
Eso tendrá un archivo con una nueva línea en el medio:
f o o s n p \n b a r . t s v
Y para probar la expansión global:
Eso agregará un asterisco que, si no está entre comillas, se expandirá a toda la lista de archivos.
fuente
supongamos que desea contar la cantidad de archivos html:
así que si estás contando ocurrencias de "snp":
fuente