J'ai un dossier avec +1000 fichiers .dat. Et chaque fichier contient plusieurs lignes du type suivant:
-0.0999999999999659-0.0000000006287859
-0.08999999999997500.8000000006183942
-0.0799999999999841-0.0000000007463807
-0.06999999999999320.0000000008661516
-0.06000000000000230.0000000008640644
-0.05000000000001140.0000000008807621
-0.0400000000000205-0.7000000009575896
-0.02999999999997270.0000000009476864
-0.01999999999998180.0000000009150902
-0.00999999999999090.0000000008144152
0.00000000000000000.0000000007097434
0.00999999999999090.0000000007847500
0.01999999999998180.0000000009030998
0.03000000000002960.0000000009741985
Pour tous les fichiers que je veux convertir en
-0.0999999999999659 -0.0000000006287859
-0.0899999999999750 0.8000000006183942
-0.0799999999999841 -0.0000000007463807
-0.0699999999999932 0.0000000008661516
-0.0600000000000023 0.0000000008640644
-0.0500000000000114 0.0000000008807621
-0.0400000000000205 -0.7000000009575896
-0.0299999999999727 0.0000000009476864
-0.0199999999999818 0.0000000009150902
-0.0099999999999909 0.0000000008144152
0.0000000000000000 0.0000000007097434
0.0099999999999909 0.0000000007847500
0.0199999999999818 0.0000000009030998
0.0300000000000296 0.0000000009741985
La seule chose qui soit cohérente dans tous ces fichiers est que le deuxième nombre (correspondant au deuxième point de chaque ligne) est toujours inférieur à 1,0 et supérieur à -1,0. Mais le premier nombre peut prendre n'importe quelle valeur réelle.
J'ai donc pensé à utiliser "trouver et remplacer" niquement pour le deuxième "point" comme suit. Trouver:
0.
Remplacer par:
0.
Je ne sais pas comment spécifier sed
uniquement pour agir sur le "deuxième point" de chaque ligne. Est-ce que quelqu'un a une bonne idée sur la façon de faire cela?
sed -E s'/(.*[^-])(-?0\.)/\1 \2/' 999.dat
Le *
est gourmand et mange le plus de caractères possible afin que le \.
corresponde toujours au dernier de la ligne. Le [^-]
garantit que le -
facultatif du deuxième numéro entre dans le deuxième groupe.
Pour ne remplacer que la deuxième occurrence, utilisez le modificateur 2
. Ainsi:
$ sed -E 's/-?[[:digit:]][.]/ &/2' file.dat
-0.0999999999999659 -0.0000000006287859
-0.0899999999999750 0.8000000006183942
-0.0799999999999841 -0.0000000007463807
-0.0699999999999932 0.0000000008661516
-0.0600000000000023 0.0000000008640644
-0.0500000000000114 0.0000000008807621
-0.0400000000000205 -0.7000000009575896
-0.0299999999999727 0.0000000009476864
-0.0199999999999818 0.0000000009150902
-0.0099999999999909 0.0000000008144152
0.0000000000000000 0.0000000007097434
0.0099999999999909 0.0000000007847500
0.0199999999999818 0.0000000009030998
0.0300000000000296 0.0000000009741985
Comment ça fonctionne:
-E
Cela indique à sed d'utiliser une expression rationnelle étendue. Ceci élimine le besoin d'échapper au ?
.
s/-?[[:digit:]][.]/ &/2
Ceci recherche un -
facultatif suivi d'un chiffre suivi d'un littéral .
. Dans le texte de remplacement, quatre espaces sont ajoutés avant la chaîne correspondante, notée &
.
Le modificateur 2
situé à la fin de la commande de substitution indique à sed de ne remplacer que la deuxième occurrence du motif.
Quelques exemples supplémentaires montrant comment différentes substitutions peuvent être effectuées:
$ echo aaaa | sed 's/a/A/1'
Aaaa
$ echo aaaa | sed 's/a/A/2'
aAaa
$ echo aaaa | sed 's/a/A/3'
aaAa
$ echo aaaa | sed 's/a/A/4'
aaaA
$ echo aaaa | sed 's/a/A/g'
AAAA
trouvez le premier point :)
sed -r 's/(.*\.[^-\.]*)(-?)0\.(.*)/\1\t\20.\3/' file
-r
utilise EREs/old/new
remplace old
par new
(some chars)
enregistrer some chars
pour faire référence ultérieurement.*
un nombre quelconque de caractères\.
littéral .
[^-\.]
tous les caractères sauf le tiret ou .
-?
facultatif -
\1\t\20.\3
imprimer les motifs sauvegardés, un onglet et 0.
aux endroits appropriésQue diriez-vous
$ sed -E 's/(-?0\.[0-9]+)(-?0\.[0-9]+)/\1\t\2/' file
-0.0999999999999659 -0.0000000006287859
-0.0899999999999750 0.8000000006183942
-0.0799999999999841 -0.0000000007463807
-0.0699999999999932 0.0000000008661516
-0.0600000000000023 0.0000000008640644
-0.0500000000000114 0.0000000008807621
-0.0400000000000205 -0.7000000009575896
-0.0299999999999727 0.0000000009476864
-0.0199999999999818 0.0000000009150902
-0.0099999999999909 0.0000000008144152
0.0000000000000000 0.0000000007097434
0.0099999999999909 0.0000000007847500
0.0199999999999818 0.0000000009030998
0.0300000000000296 0.0000000009741985
Comment ça fonctionne:
-?0\.[0-9]+
correspond à 0.
suivi d'un ou de plusieurs autres chiffres décimaux et éventuellement précédé de -
(-?0\.[0-9]+)(-?0\.[0-9]+)
capture 2 instances de ce qui précède\1\t\2
les remplacer par un TAB entre les deux