Shell lire et modifier une ligne précise

Résolu
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   -  
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour à toutes et à tous,

Voici mon fichier par exemple :

1,0000 0,673 0,005
2,0000 0,790 0,009
3,0000 0,787 0,018
4,0000 0,787 0,010
5,0000 0,792 0,016

je souhaite modifier la valeur "0,787" par "toto" par exemple mais uniquement sur la ligne 4.
En faisant : sed -i "s/"0,787"/"toto"/g" test.txt
il modifie toutes les lignes.

Comment puis je restreindre a la ligne 4 svp?

Merci d'avance
Sony
A voir également:

19 réponses

jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
Salut,
[tmpfs]$ cat plop
1,0000 0,673 0,005
2,0000 0,790 0,009
3,0000 0,787 0,018
4,0000 0,787 0,010
5,0000 0,792 0,016

[tmpfs]$ sed '4 s/0,787/toto/' plop
1,0000 0,673 0,005
2,0000 0,790 0,009
3,0000 0,787 0,018
4,0000 toto 0,010
5,0000 0,792 0,016

[tmpfs]$
;-))
1
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
Salut merci pour la reponse.

En faisant cela je vois les modifs dans la console mais le fichier ne se modifie pas. Est ce normal?

Sony
0
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896 > sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention  
 
Il suffit de remettre l'option "-i" ;-))
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
essaye ce code.
for(n=1;n<=NF;n++)x +=$n : on somme avec chaque champ de chaque ligne
m+=NF : en sommant le nombre de champs, on a à la fin le nombre total de nombres
BEGIN { x = 0 ;m = 0} : ces lignes sont superflues puisque les variables sont par défaut =0
je n'ai pas utilisé /,/./ ; essaye
export LC_NUMERIC="en_US.UTF-8"
au début du script pour n'afficher que des points dans les calculs décimaux


#!/bin/bash

for file in *.txt
do

moyenne=$(awk '
BEGIN { x = 0 ;m = 0}
{for(n=1;n<=NF;n++)x +=$n; m+=NF}
END {
moy= x / m
printf "%.2f\n", moy
}' "$file")

ecart=$(awk -v moyenne=${moyenne} '
BEGIN { x = 0 ; m = 0}
{for(n=1;n<=NF;n++)x +=( $n - moyenne ) ^ 2; m+=NF}
END {
ecar= ( x / m) ^ 0.50
printf "%.2f\n",ecar
}' "$file")

echo "${file}${moyenne},${ecart}" >> fichier.sortie
done
1
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
;) Merci bien Jipicy!

Pb réglé!

Sony
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
Arf encore moi avec un petit problème dans la même lignée...

Voilà.

J'ai un code fortran CONTNM.f :

1) SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)
2)
3) PARAMETER(MAXCLY=40)
4) .....
...) .....


Je souhaite modifier la valeur de MAXCLY avant de compiler avec un script :

#! /bin/bash

echo "MAXCLY"
read nb
sed -i '3 s/40/'$nb'/' CONTNM.f

La où j'ai pas fait gaffe c'est que maintenant MAXCLY=nb et que si je veux encore modifier sa valeur je dois modifier le script au niveau du sed.

Comment faire pour que le script écrivent MAXCLY=nb avec nb definit par l'utilisateur?

Je vous remercie d'avance,
Sony
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
[tmpfs]$ cat plop
1) SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)
2)
3) PARAMETER(MAXCLY=40)
4) .....
...) .....

[tmpfs]$ read nb
31000

[tmpfs]$ sed "3 s/40/$nb/" plop
1) SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)
2)
3) PARAMETER(MAXCLY=31000)
4) .....
...) .....

[tmpfs]$
Voir dans la FAQ : SED - Le remplacement de variable

;-))
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
ok mais comment lire la valeur 40 svp?

Sony
0
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
Comme ça :
sed "3 s/\(.*=\).*/\1$nb)/"
;-))
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
Après essai (juste sed -i "3 s/\(.*=\).*/\1$nb)/") cela ne fonctionne pas. Il me retourne un blanc et efface la valeur 40...

l'idée est de lire cette valeur (40) pour la modifier par une valeur définit par l'utilisateur...

1) SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)
2)
3) PARAMETER(MAXCLY=40)
4) .....
...) .....

**************************************************************
#! /bin/bash


echo "Nombre de couches"
read np
sed -i "3 s/\(.*=\).*/\1$nb)/" CONTNM.f
sed -i "3 s/$nb/$np/" CONTNM.f

Bien à vous,
Sony
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
PS : les 1) ,2) sont mis juste pour préciser les numéros de ligne, ils n'apparaissent pas dans le fichier.

SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)

PARAMETER(MAXCLY=40)

Sony
0
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
[tmpfs]$ cat plop
SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)

PARAMETER(MAXCLY=40)
bla bla bla
bla bla bla

[tmpfs]$ read nb
222

[tmpfs]$ sed "3 s/\(.*=\).*/\1$nb)/" plop
SUBROUTINE ABSCNT(FREQ,J,TT,ABSCNTO3)

PARAMETER(MAXCLY=222)
bla bla bla
bla bla bla

[tmpfs]$
;-))
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
Salut,

J'ai un prob avec la commande SED.

J'ai un programme fortran a exécuté sur une centaine de fichier. Donc je suis amené a modifier le nom du fichier d'entrée dans ce programme fortran.
J'ai donc fait ce petit script qui lit le nom du fichier *.dat et créé un fichier de sortie *.txt.

Mon probleme c'est qu'il n'écrit pas les noms quand je fais:
sed -i "11 s/\(.*=\).*/\1$m)/" pickout.f
sed -i "12 s/\(.*=\).*/\1$n)/" pickout.f

Votre sera très appréciable

MERCI!!!

***************
***************
Voici mon script:

#! /bin/bash

for file in *.dat
do

n=$ echo $file
m=$ echo "$file" | sed "s/dat/txt/"


echo $n
echo $m

sed -i "11 s/\(.*=\).*/\1$m)/" pickout.f
sed -i "12 s/\(.*=\).*/\1$n)/" pickout.f

f77 pickout.f -o pickout
./pickout

done
******************
******************
et mon prog fortran pickout.f :

PROGRAM pickout
INTEGER ilig, icol, idimlig, idimcol
DIMENSION rad(2399)
c Entrer la dimension colonne-ligne des images.
idimcol=2399
idimlig=1674
c Entrer la position colonne-ligne de la cible.
icol=870
ilig=906
c Lecture images et ecriture tableau.
(11) OPEN(4,FILE=)
(12) OPEN(1,FILE=)
&ACCESS='direct',RECL=4*idimcol,FORM='unformatted',STATUS=)
DO k=ilig-2,ilig+2
READ(1,REC=k) (rad(ic),ic=1,idimcol)
WRITE(4,100) (rad(ic),ic=icol-2,icol+2)
ENDDO
100 format(5(F9.4,x))
CLOSE(1)
CLOSE(4)
END
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
hello
change
n=$ echo $file
m=$ echo "$file" | sed "s/dat/txt/"
par
n=$file
m=$(echo "$file" | sed "s/dat/txt/")
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
merci ca marche!

quelle est la difference entre:

n=$ echo $file et n=$file
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
n=$file # j'assigne à n la valeur de la variable file

n=$ echo $file # j'assigne à n $ puis j'exécute echo $file

n=$(echo $file) # ceci est l'équivalent de n=$file
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
voici les noms de fichier à l'issu de l'execution de pickout:

MSG1-SEVI-MSG15-0100-NA-200611160227LST.txt
MSG1-SEVI-MSG15-0100-NA-200611160242LST.txt

etc...

contenant chacun un tableau 5*5 de la forme:

312.9490 313.6078 313.6268 313.2100 313.3503
313.3282 313.2675 314.1463 313.6644 313.6580
312.6511 314.0935 313.6562 313.0982 313.2926
312.7724 312.0528 312.3088 313.1470 312.7823
312.4456 311.9125 312.0738 312.5998 311.8029

Comment lire tout ces fichiers, faire la moyenne et l'ecartype de leur contenu et l'ecrire dans un fichier de sortie.

par exemple:

200611160227 [moyenne] [ecartype]
200611160242 [moyenne] [ecartype]
ect...

j'ai fais ca mais cela n'a pas l'air de fonctionner.

Merci d'avance

#! /bin/bash

for file in *.txt
do
name=$file

moyenne=$(cat "$file" | awk '
BEGIN {
FS=" "
x = 0
}
NR==1 , NR==$FNR {
x=x+$2
}
END {
moy= ( x / ( FNR - 1 ) )
printf "%.2f\n",moy
}')

ecart=$(cat "$file" | awk '
BEGIN {
FS=" "
x = 0
}
NR==1 , NR==$FNR {
x= x + ( $2 - '"${moyenne/,/.}"' ) ^ 2
}
END {
ecar= ( x / ( FNR - 1 ) ) ^ 0.50
printf "%.2f\n",ecar
}')

echo "${name}${moyenne/,/.},${ecart/,/.}" >> fichier.sortie
done
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
faire la moyenne et l'ecartype
de quoi ? chaque colonne , de tout les nombres d'un fichier, de la colonne 2 ?
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
de tout les nombres contenus dans le fichier
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
salut ca a l'air de fonctionner.

J'ai fais qqes controle a la main et je me suis rendu compte d'un erreur sur la valeur de l'ecartype... ca doit etre du a la precision numerique des valeurs?

MERCI
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
essaye d'imprimer plus de décimales
printf "%.8f\n", moy

printf "%.8f\n",ecar
0
sony97one Messages postés 28 Date d'inscription   Statut Membre Dernière intervention   2
 
ah ben c'etait une erreur de formule

ecar= ( x / (m-1)) ^ 0.50

et pas

ecar= ( x / m) ^ 0.50

Pb resolu merci.
0