Tout d'abord un peu de contexte: j'utilise subversion pour gérer mes sources et je lance régulièrement la commande svn st pour savoir quels sont les fichiers versionnés, ce qui me donne l'output suivant

M     test.java
?     testa.java
A     test modif.java
?     test special.java

Mon but est simple: supprimer les fichiers non versionnés. Le début est assez facile, il suffit de filtrer grâce à grep et un petit coup de awk pour ne pas afficher le premier caractère.

svn st | grep "^?" | awk '{print $2}'

Sauf que... ça ne marche pas pour les noms de fichier avec des espaces ! La commande awk va afficher le deuxième token, mais comme ceux-ci sont séparés par des espaces, seul "test" sera affiché au lieu de "test special.java". Il faut donc bidouiller un peu pour avoir le nom complet:

svn st | grep "^?" | awk '{$1=""; print $0}'

Avec cette commande, on a bien ce que l'on veut. Mais attention: il y a un espace qui préfixe chacun des noms de fichier ! Il faut donc trimmer les lignes. Pour cela, il a pleins de possibilités différentes selon les préférences de chacun, pour ma part, j'utilise simplement sed:

svn st | grep "^?" | awk '{$1=""; print $0}' | sed 's/\s*\(.*\)\s*/\1/'

Dernière astuce: il ne faut pas utiliser un for la-dessus car ça ne marchera pas s'il y a des espaces dans les noms de fichiers. Par contre, il est possible de simplement utiliser la commande xargs qui permet de spécifier un délimiteur:

svn st | grep "^?" | awk '{$1=""; print $0}' | sed 's/\s*\(.*\)\s*/\1/' | xargs --delimiter='\n' rm

Pour finir, voici une petite fonction à mettre dans votre .bashrc afin de pouvoir simplement appeler trim quand vous en aurez besoin:

function trim() {
        while read line
        do
                echo "$line" | sed 's/\s*\(.*\)\s*/\1/'
        done < "${1:-/dev/stdin}"
}

Cette fonction peut aussi bien s'utiliser avec un pipe ou avec un fichier:

echo "   abcd   " | trim
trim "chemin/vers/fichier"