2009-12-10 4 views
0

J'ai fichier de données qui stocke les enregistrements comme ceci:Quelle est la meilleure façon de modifier un enregistrement de fichier texte en utilisant shell?

make=honda|model=civic|color=red 
make=toyota|model=corolla|color=blue 

Quelle serait la meilleure façon de détecter (en fonction du champ de marque) si une marque donnée existe dans le fichier, puis le remplacer par un nouveau record ? (À l'aide du script shell)

+0

vous avez montré votre fichier de données, montrent maintenant votre fichier réel que vous voulez faire une modification et décrire votre sortie finale par des exemples – ghostdog74

Répondre

2

Pour vos besoins, la meilleure solution est probablement the stream editor ou awk.

+0

Je sais déjà comment détecter l'enregistrement (awk). Mais y a-t-il un bon moyen de le remplacer? Puis-je utiliser SED en quelque sorte pour le faire? – goe

+0

Si seulement il y avait un moyen de transformer les mots "l'éditeur de flux" dans une sorte de portail magique à la documentation pour lui-même ... –

0

Cela devrait le faire en bash.

#get the file and create an array separated by new lines 
lines=$(cat $filename) 
IFS=$'\n' 
lines=($lines) 
unset IFS 


for line in ${lines[@]} 
do 
    #Get the value of make from the current line 
    make=$(echo "$line" | cut -d "|" -f1 | cut -d "=" -f2) 

    if [[ "$make" == "$makeImLookingFor" ]] 
    then 
     echo "modified line" 
    else 
     echo "$line" 
    fi 
done 
2

Voici un script qui utilise une commande sed qui le fera:

filename='cars' 
make='toyota' 
replacement='make=nissan|model=sentra|color=green' 
sed "s/^make=$make.*/$replacement/" $filename 

Il y a quelques problèmes avec la réponse de icarus127 que je fixe et adressé ici:

filename='cars' 
saveIFS="$IFS" 
IFS=$'\n' 
# no need to call external cat, make the array at the same time the file is read 
lines=($(<$filename)) 
# IMO, it's better and makes a difference to save and restore IFS instead of unsetting it 
IFS="$saveIFS" 

make='toyota' 
replacement='make=nissan|model=sentra|color=green' 

# the array variable MUST be quoted here or it won't work correctly 
for line in "${lines[@]}" 
do 
    # you can use Bash's regex matching to avoid repeatedly calling 
    # multiple external programs in a loop 
    if [[ $line =~ ^make=$make ]] 
    then 
     echo "$replacement" 
    else 
     echo "$line" 
    fi  
done 

Cependant, que (et les vers cat ion) lit le fichier entier dans un tableau, ce qui pourrait être un problème s'il est grand. Il est préférable d'utiliser read dans une boucle while avec une redirection:

filename='cars' 

make='toyota' 
replacement='make=nissan|model=sentra|color=green' 

while read -r line 
do 
    # you can use Bash's regex matching to avoid repeatedly calling 
    # multiple external programs in a loop 
    if [[ $line =~ ^make=$make ]] 
    then 
     echo "$replacement" 
    else 
     echo "$line" 
    fi  
done < "$filename" 
+0

+1 Pour améliorer mon script. Je suis au mieux un novice et c'est génial de voir de meilleures façons de faire les choses. Merci :) – asm

0

par sed c'est est un moyen

contenu de temp.txt make = honda | modèle = civique | color = red make = toyota | modèle = corolla | color = blue

new_rec = "make = honda | modèle = civique | color = blue".

$ sed -e « s/^ make = honda */$ new_rec/g "temp.txt make = honda | modèle = c CICV | color = blue make = toyota | modèle = corolla | color = blue

espérons que cette aide

Questions connexes