Intentando crear un script de shell para buscar un directorio de forma recursiva y mostrar una lista de todos los archivos php que solo contienen 1 línea
Creo que algo está mal con mi declaración IF pero no estoy seguro
#!/bin/bash shopt -s nullglob for f in *.php do if [ 'find . -type f | wc -l $f == 1' ]; then echo "$f" fiEsto encontrará "frases de una sola línea":
find . -type f -name '*.php' -exec grep -Hcm2 $ {} + | sed -n '/:1$/{s///;p}'Este encontrará "frases de una sola línea" que tienen más de una línea, cuando todas las líneas excepto una están en blanco:
find . -type f -name '*.php' -exec grep -Hcm2 '[^[:space:]]' {} + | sed -n '/:1$/{s///;p}' Las opciones de grep -Hcm2 significan "Siempre imprime el nombre del archivo, solo imprime el recuento de las coincidencias y coincide como máximo con dos líneas". El patrón $ coincide con cualquier línea, mientras que el patrón "[^[:space:]]" coincide con cualquier línea que contenga un carácter que no sea un espacio en blanco. Terminar el -exec con {} + le dice a find que proporcione una lista de archivos en lugar de activar el exec en cada archivo, lo que es mucho más eficiente. Finalmente, sed imprime las líneas que terminan con :1 (después de eliminar :1 ), que serán los nombres de archivo de los archivos para los que el recuento de líneas que contienen un carácter que no sea un espacio en blanco fue exactamente uno.
Podría decirse que esto es más eficiente que wc porque normalmente deja de leer en la segunda línea, en lugar de leer archivos completos solo para verificar si tienen más de una línea.
(Además, con respecto a wc : si el archivo tiene exactamente una línea, pero esa línea no termina con un carácter de nueva línea, entonces wc informará que tiene 0 líneas. Entonces, si está filtrando la salida de wc para que sea igual a 1, puede perder algunos archivos).
Si tiene un bash razonablemente reciente, puede evitarlo habilitando ** find :
shopt -s globstar nullglob grep -Hcm2 "[^[:space:]]" **/*.php | sed -n '/:1$/{s///;p}'Ninguno de los trucos anteriores funciona si tiene archivos con caracteres de nueva línea en sus rutas de archivo. Pero tú no, ¿verdad? :-)
¡ awk al rescate!
for f in *.php; do awk 'END{ if(NR==1) print FILENAME}' $f; donepara la búsqueda recursiva que necesita usar find, una alternativa puede ser
find -name *.php -print | xargs -L1 awk 'NR>1{exit} END{if(NR==1) print FILENAME}'Esto buscará recursivamente archivos PHP de una línea:
find -name '*.php' -exec bash -c '[[ "$(wc -l < "$0")" -eq 1 ]] && echo "$0"' '{}' ';' Si desea probar el éxito o el fracaso de un comando en una declaración if , no use el operador [ , sino que escríbalo después de if directamente:
if find . -type f | wc -l $f == 1; then echo "$f" fiSin embargo, lo que escribí anteriormente todavía no tiene mucho sentido y no es lo que creo que pretendías.
El [ en sí mismo es un comando que se usa para convertir la comparación aritmética y de cadenas en una forma compatible con if . Puede combinarlo con la sustitución de salida (usando la sintaxis $(...) ) para probar si la salida de un comando es igual a 1.
if [ "$(wc -l < "$f")" -eq 1 ]; then echo "$f" fi