Tengo muchos archivos (con .fna
extensión). Necesito moverlos, si contienen el personaje.>un cierto número de veces.
Sé qué archivos contienen>un cierto número de veces (9 veces en este ejemplo) con este comando.
grep -c ">" *.fna | grep ":9"
Lo que da una salida como esta
5242_ref.fna:9
9418_ref.fna:9
Pero no sé cómo mover esos archivos a otra carpeta.
Gracias.
Respuesta1
Combinando egrep
(llamado con la -l
opción para que las coincidencias positivas devuelvan solo nombres de archivos) conxargs
puedes realizar comandos arbitrarios basados en coincidencias de texto:
[gnubeard@mothership: ~/mver]$ ls
destination example.fna non_example.fna
[gnubeard@mothership: ~/mver]$ cat example.fna
>>>>>>>>>
[gnubeard@mothership: ~/mver]$ cat non_example.fna
<<<<<<<<<
>>
[gnubeard@mothership: ~/mver]$ egrep -l '>{9}' *.fna | xargs -I{} mv {} destination/
[gnubeard@mothership: ~/mver]$ ls
destination non_example.fna
[gnubeard@mothership: ~/mver]$ ls destination/
example.fna
Editar: esto no coincide con archivos con una cierta cantidad de instancias de un carácter, si están separados por otros caracteres o nuevas líneas. He creado este breve script que debería funcionar como se desea.
#! /usr/bin/env bash
DESTINATION=./destination
MATCH_CHAR='>'
MATCH_COUNT=9
for FILE in $1; do
MATCHES=$(grep -o $MATCH_CHAR $FILE | wc -l)
if [ $MATCHES -eq $MATCH_COUNT ]; then
mv $FILE $DESTINATION
fi
done
Ejemplo:
[gnubeard@mothership: ~/mver]$ ls
destination example.fna mver non_example.fna
[gnubeard@mothership: ~/mver]$ cat example.fna
>>
>>foo>>bar>>>baz
[gnubeard@mothership: ~/mver]$ cat non_example.fna
<<<<<<<<<
>>
[gnubeard@mothership: ~/mver]$ ./mver *.fna
[gnubeard@mothership: ~/mver]$ ls destination/
example.fna
[gnubeard@mothership: ~/mver]$ ls
destination mver non_example.fna
Respuesta2
Podrías usar zsh con suexpresión-como-calificador-globpara seleccionar archivos que solo tengan nueve de estos símbolos:
$ hasnine() { [[ $(tr -dc '>' < "$REPLY" | wc -c) -eq 9 ]]; }
$ mv *.fna(+hasnine) location/
La primera línea define una función cuyo propósito es crear un filtro verdadero/falso para archivos que contienen nueve >
símbolos. El tr
comando actúa sobre su entrada, esperada en la REPLY
variable, eliminando todo lo que no sea un >
, luego solicita wc
contar el número de caracteres resultantes y luego compara esa salida con 9.
La segunda línea ejecuta el mv
comando para hacer coincidir los archivos *.fna con el location
directorio (ejemplo). Los archivos *.fna coincidentes también deben pasar el calificador de expresión, que se proporciona como el nombre de la función que definimos.