2010-11-17 17 views
1

Un exemple simplifié de ce que je veux faire:texte complexe remplacer à partir de la ligne de commande

J'ai un fichier: input.txt qui ressemble à

a 2 4 b 
a 3 8 b 
c 9 4 d 
a 3 4 8 b 

et un script: add.sh qui prend les paramètres de ligne de commande et retourne leur somme

Je veux rechercher input.txt pour toutes les instances du modèle 'a (.*) b' où je passe la partie (. *) comme paramètre de ligne de commande à add.sh. Par exemple, je veux faire quelque chose comme sed 's/a \(.*\) b/a {add.sh \1} b/g' input.txt (cela ne marche bien sûr pas). Ainsi, la sortie devrait ressembler à

a 6 b 
a 11 b 
c 9 4 d 
a 15 b 

Quelle serait la meilleure façon de le faire?

Merci

Répondre

0
perl -pe 's/a (.*) b/"a ".`add.sh $1`." b"/eg' input.txt 

Assurez-vous que add.sh ne sort pas une nouvelle ligne.

0

Et si perl est pas une option, vous pourriez script, il quelque chose comme ceci:

grep -e '^a .* b$' input.txt | sed -e 's/a \(.*\) b/\1/g' | while read LINE; do ./add.sh $LINE; done 

Je réalise ce qui précède ne résout pas votre problème, je me suis concentré sur votre sed expression.

Cependant, si vous êtes désireux de résoudre ce problème en utilisant un autre script shell, il ressemblerait probablement quelque chose comme ceci:

cat input.txt | while read LINE; do 
    if [[ "$LINE" =~ ^a (.*) b$ ]]; then 
     echo -n "a " 
     add.sh ${BASH_REMATCH[1]} 
     echo " b" 
    else 
     echo $LINE 
    fi 
done 
0

Si add.sh est:

#!/bin/sh 
arg1=$1 
nums=$2 
shift 2 
for i in $nums 
do 
    sum=$((sum+i)) 
done 
echo "$arg1 $sum [email protected]" 

vous pourriez faire:

sed 's/^\([^ ]* \)\(.*\)\([^ ]*\)$/\1\"\2\"\3/' input.txt | xargs -L 1 ./add.sh 

qui ajouterait les nombres sur chaque ligne. Pour les ajouter que pour les lignes qui commencent par « a » et se terminent par « b » utiliser: ligne

sed 's/^a \(.*\) b$/a \"\1\" b/' input.txt | xargs -L 1 ./add.sh 

Le « c 9 4 d » est toujours traitée par add.sh mais la commande sed n'ajoute aucun guillemets, donc le script ne voit que "9" comme $2 et donc la somme n'est faite qu'une seule fois avec le résultat "9". Le "4" est considéré comme faisant partie du reste de [email protected].