characters bash whitespace

bash - characters - ¿Cómo eliminar los espacios en blanco finales de todos los archivos recursivamente?



trim unix shell (14)

¿Cómo puede eliminar todos los espacios en blanco finales de un proyecto completo? Comenzando en un directorio raíz y eliminando el espacio en blanco final de todos los archivos en todas las carpetas.

Además, quiero poder modificar el archivo directamente y no solo imprimir todo en stdout.


ex

Intenta usar el editor Ex (parte de Vim):

$ ex +''bufdo!%s//s/+$//e'' -cxa **/*.*

Nota: Para la recursividad (bash4 y zsh), usamos una nueva opción globbing ( **/*.* ). Habilitado por shopt -s globstar .

Puede agregar la siguiente función a su .bash_profile :

# Strip trailing whitespaces. # Usage: trim *.* # See: https://.com/q/10711051/55075 trim() { ex +''bufdo!%s//s/+$//e'' -cxa $* }

sed

Para usar sed , compruebe: ¿Cómo eliminar los espacios blancos finales con sed?

find

Busque la siguiente secuencia de comandos (por ejemplo, remove_trail_spaces.sh ) para eliminar los espacios en blanco finales de los archivos:

#!/bin/sh # Script to remove trailing whitespace of all files recursively # See: https://.com/questions/149057/how-to-remove-trailing-whitespace-of-all-files-recursively case "$OSTYPE" in darwin*) # OSX 10.5 Leopard, which does not use GNU sed or xargs. find . -type f -not -iwholename ''*.git*'' -print0 | xargs -0 sed -i .bak -E "s/[[:space:]]*$//" find . -type f -name /*.bak -print0 | xargs -0 rm -v ;; *) find . -type f -not -iwholename ''*.git*'' -print0 | xargs -0 perl -pi -e ''s/ +$//'' esac

Ejecute este script desde el directorio que desea escanear. En OSX al final, eliminará todos los archivos que terminan en .bak .

O solo:

find . -type f -name "*.java" -exec perl -p -i -e "s/[ /t]$//g" {} /;

que es la forma recomendada por Spring Framework Code Style .


1) Muchas otras respuestas usan -E . No estoy seguro de por qué, ya que esa es la opción de compatibilidad BSD no documentada . -r debe usar en su lugar.

2) Otras respuestas usan -i '''' . Eso debería ser solo -i (o -i'''' si se prefiere), porque -i tiene el sufijo inmediatamente después.

3) Solución específica de Git:

git config --global alias.check-whitespace / ''git diff-tree --check $(git hash-object -t tree /dev/null) HEAD'' git check-whitespace | grep trailing | cut -d: -f1 | uniq -u -z | xargs -0 sed --in-place -e ''s/[ /t]+$//''

El primero registra un git alias check-whitespace que enumera los archivos con espacios en blanco al final. El segundo corre sed sobre ellos.

Solo uso /t lugar de [:space:] ya que normalmente no veo las pestañas verticales, las alimentaciones de formularios ni los espacios no rompibles. Su medida puede variar.


Ack fue creado para este tipo de tarea.

Funciona igual que grep, pero sabe que no debe descender a lugares como .svn, .git, .cvs, etc.

ack --print0 -l ''[ /t]+$'' | xargs -0 -n1 perl -pi -e ''s/[ /t]+$//''

Mucho más fácil que saltar a través de aros con find / grep.

Ack está disponible a través de la mayoría de los administradores de paquetes (ya sea como ack o ack-grep ).

Es solo un programa Perl, por lo que también está disponible en una versión de archivo único que puede descargar y ejecutar. Ver: Ack Instalar


Aquí hay una solución OS X> = 10.6 Snow Leopard.

Ignora las carpetas .git y .svn y sus contenidos. Tampoco dejará un archivo de respaldo.

find . -not /( -name .svn -prune -o -name .git -prune /) -type f -print0 | xargs -0 sed -i '''' -E "s/[[:space:]]*$//"


Dos enfoques alternativos que también funcionan con líneas nuevas de DOS (CR / LF) y hacen un buen trabajo para evitar archivos binarios :

Solución genérica que verifica que el tipo MIME comience con text/ :

while IFS= read -r -d '''' -u 9 do if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]] then sed -i ''s/[ /t]/+/(/r/?/)$//1/'' -- "$REPLY" else echo "Skipping $REPLY" >&2 fi done 9< <(find . -type f -print0)

Solución específica del repositorio de Git por Mat que usa la opción -I de git grep para omitir archivos que Git considera binarios:

git grep -I --name-only -z -e '''' | xargs -0 sed -i ''s/[ /t]/+/(/r/?/)$//1/''


En Bash:

find dir -type f -exec sed -i ''s/ *$//'' ''{}'' '';''

Nota: Si está utilizando .git repositorio .git , intente agregar: -not -iwholename ''.git'' .


En lugar de excluir archivos, aquí hay una variación de las listas explícitamente blancas de los archivos, basados ​​en la extensión de archivo, que desea quitar, siéntase libre de condimentar:

find . /( -name *.rb -or -name *.html -or -name *.js -or -name *.coffee -or / -name *.css -or -name *.scss -or -name *.erb -or -name *.yml -or -name *.ru /) / -print0 | xargs -0 sed -i '''' -E "s/[[:space:]]*$//"


Esto es lo que funciona para mí (Mac OS X 10.8, GNU sed instalado por Homebrew):

find . -path ./vendor -prune -o / /( -name ''*.java'' -o -name ''*.xml'' -o -name ''*.css'' /) / -exec gsed -i -E ''s//t/ /'' /{} /; / -exec gsed -i -E ''s/[[:space:]]*$//'' /{} /; / -exec gsed -i -E ''s//r/n//n/'' /{} /;

Se eliminaron los espacios finales, reemplaza las pestañas con espacios, reemplaza Windows CRLF con Unix /n .

Lo que es interesante es que tengo que ejecutar esto 3-4 veces antes de que se arreglen todos los archivos, por todas las instrucciones de limpieza.


Esto funcionó para mí en OSX 10.5 Leopard, que no usa GNU sed o xargs.

find dir -type f -print0 | xargs -0 sed -i.bak -E "s/[[:space:]]*$//"

Solo tenga cuidado con esto si tiene archivos que necesitan ser excluidos (¡lo hice)!

Puede usar -prune para ignorar ciertos directorios o archivos. Para archivos Python en un repositorio de git, podrías usar algo como:

find dir -not -path ''.git'' -iname ''*.py''


Esto funciona bien .. add / remove - include para tipos de archivos específicos:

egrep -rl '' $'' --include *.c * | xargs sed -i ''s//s/+$//g''


Rubí:

irb Dir[''lib/**/*.rb''].each{|f| x = File.read(f); File.write(f, x.gsub(/[ /t]+$/,"")) }


Terminé ejecutando esto, que es una mezcla entre la versión de pojo y adams.

Limpiará tanto el espacio en blanco al final como también otra forma de espacio en blanco al final, el retorno del carro:

find . -not /( -name .svn -prune -o -name .git -prune /) -type f / -exec sed -i ''s/[:space:]+$//'' /{} /; / -exec sed -i ''s//r/n$//n/'' /{} /;

No tocará la carpeta .git si hay una.

Editar : lo hizo un poco más seguro después del comentario, no permitiendo tomar archivos con ".git" o ".svn" en él. Pero ten cuidado, tocará archivos binarios si tienes algunos. Use -iname "*.py" -or -iname "*.php" after -type f si solo desea que toque, por ejemplo, .py y .php-files.

Actualización 2 : ahora reemplaza todo tipo de espacios al final de la línea (lo que significa también pestañas)


Terminé no usando find y no creando archivos de respaldo.

sed -i '''' ''s/[[:space:]]*$//g'' **/*.*

Dependiendo de la profundidad del árbol de archivos, esta (versión más corta) puede ser suficiente para sus necesidades.

NOTA: esto también toma archivos binarios, por ejemplo.


Utilizar:

find . -type f -print0 | xargs -0 perl -pi.bak -e ''s/ +$//''

si no desea que se generen los archivos ".bak":

find . -type f -print0 | xargs -0 perl -pi -e ''s/ +$//''

como usuario de zsh, puede omitir la llamada para buscar y, en su lugar, usar:

perl -pi -e ''s/ +$//'' **/*

Nota: Para evitar la destrucción del directorio .git , intente agregar: -not -iwholename ''*.git*'' .