2010-03-16 3 views
7

J'essaie d'écrire un script qui recherche un fichier dans un répertoire et où il trouve un motif. Quelque chose de similaire au ci-dessous, sauf l'expression de trouver est beaucoup plus compliquée (exclut les répertoires et fichiers particuliers).Suppression de l'argument de script bash final

#!/bin/bash 
if [ -d "${!#}" ] 
then 
    path=${!#} 
else 
    path="." 
fi 

find $path -print0 | xargs -0 grep "[email protected]" 

De toute évidence, le précède ne fonctionne pas parce que "[email protected]" contient encore le chemin. J'ai essayé des variantes de construire une liste d'arguments par itérer sur tous les arguments pour exclure chemin tels que

args=${@%$path} 
find $path -print0 | xargs -0 grep "$path" 

ou

whitespace="[[:space:]]" 
args="" 
for i in "${@%$path}" 
do 
    # handle the NULL case 
    if [ ! "$i" ] 
    then 
     continue 
    # quote any arguments containing white-space 
    elif [[ $i =~ $whitespace ]] 
    then 
     args="$args \"$i\"" 
    else 
     args="$args $i" 
    fi 
done 

find $path -print0 | xargs -0 grep --color "$args" 

mais elles ne réussissent pas avec l'entrée cité. Par exemple,

# ./find.sh -i "some quoted string" 
grep: quoted: No such file or directory 
grep: string: No such file or directory 

Notez que si [email protected] ne contient pas le chemin, le premier script ne fait ce que je veux.


EDIT: Merci pour les grandes solutions! Je suis allé avec une combinaison des réponses:

#!/bin/bash 

path="." 
end=$# 

if [ -d "${!#}" ] 
then 
    path="${!#}" 
    end=$((end - 1)) 
fi 

find "$path" -print0 | xargs -0 grep "${@:1:$end}" 

Répondre

8

EDIT:

originale était légèrement. Aucune suppression ne doit être effectuée si le dernier argument n'est pas un répertoire.

#!/bin/bash 
if [ -d "${!#}" ] 
then 
    path="${!#}" 
    remove=1 
else 
    path="." 
    remove=0 
fi 

find "$path" -print0 | xargs -0 grep "${@:1:$(($#-remove))}" 
+1

C'est vraiment élégant. –

+1

+1 J'ai appris 2 choses de votre réponse, et j'utilise intensément depuis plus de 10 ans – Tino