¿Cuál es el comando de línea de comandos de Linux que puede identificar dichos archivos?
AFAIK el find
comando (o grep
) solo puede coincidir con una cadena específica dentro del archivo de texto. Pero quiero hacer coincidir todo el contenido, es decir, quiero ver qué archivos coinciden con la expresión regular \0+
, ignorando los caracteres de final de línea . Tal vez el find . cat | grep
idioma podría funcionar, pero no sé cómo hacer grep ignorando líneas (y tratar el archivo como binario).
Antecedentes: cada pocos días, cuando mi computadora portátil se congela, mi partición btrfs pierde información: los archivos abiertos para escritura reemplazan sus contenidos con ceros (el tamaño del archivo permanece más o menos intacto). Uso la sincronización y no quiero que se propaguen estos archivos falsos: necesito una forma de identificarlos para poder tomarlos de la copia de seguridad.
fuente
-v
opción de grep: filtrar todos los archivos que tienen cualquier byte de 1 a 255.Respuestas:
Puedes
grep
usar ␀ caracteres usando el modo Perl regex:Entonces puedes usar esto:
fuente
GNU grep 2.5.4
. Independientemente de si uso--binary-files=text
o--binary-files=binary
, da untrue
resultado para todos los valores de datos no vacíos, por ejemplo."\0\0"
,"\0x\0"
,"abcd"
... El código exacto que utiliza es:for typ in binary text ;do for dat in '\0\0' '\0x\0' 'abcd' '' ;do printf "$dat" >f; grep --binary-files=$typ -P '[^\0]' f >/dev/null && echo true || echo false; done; done
GNU grep) 2.10
. Esta última versión da los resultados esperados ... entonces, un tardío +1printf '\0\n\0\0\n\n' > file
oprintf '\n' > file
para eso importa.\0
y\n
personajes (incluso cero de cualquiera) sería un partido.Estoy de acuerdo con lo que D_Bye dice acerca de encontrar la raíz del problema.
De todos modos, para verificar si un archivo solo contiene
\0
y / o\n
podría usartr
:Que devuelve 0 para nulo / nueva línea y archivos vacíos.
fuente
tr -d '\0\n'
resuelve el problema de la nueva línea, que luego solo deja el problema (?) de los archivos vacíos que se enumeran en la salida ... Sin embargo, procesa cada byte de cada archivo (lo que puede o no ser un problema) +1Sospecho que esos archivos son escasos, es decir, no tienen espacio en disco asignado, solo especifican un tamaño de archivo (
du
informarían 0 para ellos).En ese caso, con GNU find, podría hacer (suponiendo que ninguna ruta de archivo contenga caracteres de nueva línea):
fuente
du
evitará rayar el contenido de cada archivo en el sistema de archivos, por lo que todo el procedimiento no tomaría más de 30 minutos en completarse.printf %b
arriba informa quédu
informaría)-size +0
a-size +1
para que los archivos de longitud cero se excluyan de los resultados. También los archivos que contienen\n
en su ruta causarán problemas para este comando.-size +0
es para tamaños estrictamente mayores que 0.-size +1
sería para tamaños estrictamente mayores que 512. La limitación de la nueva línea ya se mencionó.-size +1
, de hecho, tienes razón. He arreglado mi respuesta. :-)Aquí hay un pequeño programa de Python que puede hacerlo:
Y en acción:
Puede comprobar varios archivos mediante el uso de Find
-exec
,xargs
, GNUparallel
, y programas similares. Alternativamente, esto imprimirá los nombres de archivo que deben tratarse:Tenga en cuenta que si va a pasar la salida de este a otro programa, los nombres de archivo pueden contener nuevas líneas, por lo que debe delimitarlo de manera diferente (adecuadamente, con
\0
).Si tiene muchos archivos, sería mejor usar una opción para el procesamiento en paralelo, ya que esto solo lee un archivo a la vez.
fuente
/etc/nologin
,~/.hushlogin
,.nomedia
, ...) están mal identificados por esta respuesta.Busque archivos que contengan solo caracteres nulos '\ 0' y caracteres de nueva línea '\ n'.
El
q
in sed hace que cada búsqueda de archivo se cierre inmediatamente al encontrar cualquier carácter no nulo en una línea.Hacer archivos de prueba
salida
fuente
-print0
parece que falta el argumentofind
o laIFS=
parte está en mal estado. ¿Cuál fue el delimitador previsto?Esta sola línea es la forma más eficaz de encontrar el 100% nul archivos usando GNU
find
,xargs
ygrep
(suponiendo que este último está construido con el apoyo PCRE):Las ventajas de este método sobre otras respuestas proporcionadas son:
Permission denied
advertencias.grep
dejará de leer datos de los archivos después de encontrar cualquier byte que no sea nulo (LC_ALL=C
se utiliza para asegurarse de que cada byte se interprete como un carácter ).grep
procesos verifican eficientemente múltiples archivos.-
se manejan correctamente.Pasar la
-Z
opción aygrep
usarlaxargs -r0 ...
permite realizar más acciones en los archivos 100% nul (por ejemplo: limpieza):También recomiendo usar las
find
opciones-P
para evitar seguir enlaces simbólicos y-xdev
para evitar el desplazamiento de sistemas de archivos (por ejemplo: montajes remotos, árboles de dispositivos, montajes de enlace, etc.).Para ignorar los caracteres finales de línea , la siguiente variante debería funcionar (aunque no creo que sea una buena idea):
Poniendo todo junto, incluida la eliminación de los archivos no deseados (100% nul / caracteres de nueva línea) para evitar que se realicen copias de seguridad:
No recomiendo incluir archivos vacíos (cero bytes), a menudo existen para propósitos muy específicos .
fuente
\0
con un agujero de 900MB) y momento actual de los resultados. Si lo hace de una manera que el punto de referencia es convincente para usted, lo más probable es que sea convincente para todos nosotros-P
es el valor por defecto enfind
. Si quieres seguir enlaces simbólicos, es-L
/-follow
. Encontrará que POSIX ni siquiera especifica esa opciónfind
(aunque POSIX fue quien introdujo esos -P / -H / -L para algunos comandos).Para usar GNU sed puede usar la
-z
opción, que define una línea como cadenas terminadas en cero y hacer coincidir y eliminar líneas vacías de esta manera:El comando head en el medio es solo una optimización.
fuente
Pitón
Archivo único
Defina el alias:
Pruébalo:
Archivos múltiples
Encuentra todos los archivos binarios de forma recursiva:
Para buscar todos los archivos no binarios, cambie
&&
con||
.fuente