Je travaille sur un script bash qui recherchera un fichier spécifique en utilisant le chemin générique pour rechercher, une fois qu’il trouve ce nom de fichier qu’il recherche dans le fichier pour un terme spécifique et le remplace ensuite.
Voici ce que j’ai déjà mis en place:
#!/bin/sh PATH=${1} FILENAME="$2" SEARCHFOR="$3" /usr/bin/clear echo "Searching $PATH" echo "For the file $FILENAME" echo "With the ssortingng $SEARCHFOR" echo "==========================" echo " RESULTS " echo "==========================" /usr/bin/find $PATH -type f -name "$FILENAME" | /usr/bin/xargs /bin/grep -l "$SEARCHFOR"
Je n’ai pas encore ajouté le remplacement mais j’ai pensé que j’utiliserais SED au lieu de grep pour le faire, en utilisant simplement grep à des fins de test.
Avec le code ci-dessus, je dois utiliser des guillemets pour tout type de chemin d’access générique. Y a-t-il un moyen de contourner ceci?
./script '/home/*/public_html' php.ini module.so
Je pensais peut-être utiliser des arguments, mais il doit y avoir une autre façon de le faire.
Mon but ultime est d’avoir un script bash auquel je peux transmettre un chemin d’access ou un nom de fichier, il recherchera ce fichier, une fois qu’il trouvera le fichier qu’il recherchera pour un terme spécifique et le remplacera s’il est trouvé.
Ça a l’air si simple et ça devrait être le cas mais je me tape la tête contre le bureau parce que ça fait tellement longtemps que je n’ai pas réussi à me défoncer avec bash … aaggghh aide!
Tout d’abord, c’est une mauvaise idée d’avoir des noms de variables en majuscules, en particulier PATH
puisque vous seriez en train de réinitialiser la variable d’environnement PATH
(faites simplement un echo $PATH
dans l’invite et comprendre ce que je veux dire, et c’est probablement l’une des raisons pour lesquelles vous avez dû utiliser /usr/bin/clear
au lieu de clear
puisque la variable env PATH
est modifiée). Donc, il est toujours recommandé d’utiliser des variables avec des minuscules comme path
.
Le problème auquel vous êtes confronté concerne l’expansion glob
de *
dans le sous-shell. Lorsque vous utilisez
./script '/home/*/public_html' php.ini module.so
le *
n’est pas développé à l’invite (shell parent) mais est développé dans le sous-shell du script. Mais quand vous utilisez
./script /home/*/public_html php.ini module.so
le *
est développé dans le shell parent (ce qui se traduirait par un chemin aléatoire comme indiqué par le shell) et est ensuite transmis dans le sous-shell du programme –
Alors, /home
a des répertoires /user
, /apps
, /data
making $ cd *
vous amènera au répertoire qui est alphabétiquement en premier, à savoir /apps
. Donc /home/*
sans les guillemets dans le shell parent pointera toujours vers /home/apps
ce qui n’est pas ce que nous voulons!
Un remède immédiat à cela est comme ci-dessous
$set -o noglob #unset glob expansion $./script /home/*/public_html php.ini module.so #your command without quotes & wildcard */ $set +o noglob #re-set glob expansion back
ou
$set -o noglob;./script /home/*/public_html php.ini module.so;set +o noglob
Essayez $echo *
puis $set -o noglob;echo *;set +o noglob
pour un exemple rapide.
Avertissement – Si vous échouez ou oubliez de remettre noglob
( set +o noglob
), le shell traitera les caractères comme *
et ?
comme des personnages normaux et ne les élargira pas, ce qui pourrait entraîner des résultats indésirables et de la confusion.
find $path -name \*$filenamepattern\* -exec sed -i.bak 's/find/replace/g' {} ';'
Réorganisez simplement vos arguments et mettez la liste des répertoires à rechercher à la fin. Alors:
#!/bin/sh FILENAME="${1?No filename specified}" SEARCHFOR="${2?No target ssortingng given}" shift; shift; SEARCHPATH="$@"
Vous devriez alors être en mesure de laisser le rest inchangé (autre que de changer le nom PATH en SEARCHPATH, car changer le PATH est une très mauvaise idée) et l’appeler comme:
$ ./script php.ini module.so /home/*/public_html
find `filepath` -name `filename`|xargs sed 's/find/replace/'
pour moi, j’utiliserais find et sed pour terminer le travail.
Cela résoudra le problème du passage de caractères génériques à un script bash, mais veuillez respecter le premier point.
#!/bin/bash -f directory=$1 filename=$2 searchfor=$3 replacement=$4 sedpattern=s/$searchfor/$replacement/g find $directory -name $filename -exec sed -i.bak $sedpattern {} ';'
% ./thisscript . \*.csv oldword newword