Rechercher : dans
Par :

Aide commande ed/sed/awk/perl

Dernière réponse le 22 mai 2009 à 17:11:30 vanhell, le 20 mai 2009 à 10:28:03 
 Signaler ce message aux modérateurs

Bonjour,
J'aimerai dans un fichier texte, supprimer tous les retours à la ligne seulement pour le texte contenu entre motcle1 et motcle2 (la ligne de motcle1 incluse) et laisser le reste du texte inchangé.
motcle1 et motcle2 sont toujours en début de ligne.

Par exemple :

texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte

doit devenir :

texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte
motcle2
texte texte
texte

Comment faire ça avec sed? (ou autre)
Merci d'avance pour votre aide!

Configuration: UNIX
KSH

Meilleures réponses pour « Aide commande ed/sed/awk/perl » dans :
Sed - Introduction à SED - Part I Voir SED - The Stream EDitor - Part I Ce document est une introduction à la pratique et à l'utilisation de l'éditeur de flux "SED", qui essaie de couvrir certaines fonctionnalités assez méconnues, pour ne pas dire "quasi inconnues", qui font de "SED" un...
Transformer des colonnes en lignes dans un fichier VoirDifférents outils de Linux sont très doués pour travailler avec des lignes, mais pas avec des colonnes (c'est leur rôle) Sed, Awk, Grep, etc. Cependant, il peut arriver pour X raisons que vous ayez un fichier où les données sont à lire en...
Comment récupérer le résultat d'une commande dans une variable VoirComment récupérer le résultat d'une commande dans une variable Préambule Syntaxe Exemples Préambule Il est bien souvent nécessaire de récupérer le résultat d'une commande (ou de son code retour) dans une variable afin de pouvoir...
Liste des commandes Windows VoirRemarques : Certaines commandes sont dangereuses (l’exemple de SYSKEY) et peuvent causer des problèmes pouvant conduire au formatage. D’autres commandes ne sont pas exécutables sous Windows XP ou des versions antérieures, je ne les ai pas...
Commandes Linux VoirTableau des principales commandes Linux Commande Description équivalent DOS ls liste le contenu d'un répertoire dir cd change de répertoire cd cd .. répertoire parent cd.. mkdir crée un nouveau...
Attaques par injection de commandes SQL VoirInjection de commandes SQL Les attaques par injection de commandes SQL sont des attaques visant les sites web s'appuyant sur des bases de données relationnelles. Dans ce type de sites, des paramètres sont passés à la base de données sous forme...
Commandes UNIX VoirTableau des principales commandes UNIX Commande Unix Description Options ls liste le contenu d'un répertoire -a Affiche tous les fichiers, y compris les fichiers cachés ...

1

jipicy, le 20 mai 2009 à 10:46:35

Salut,

sed '/motcle1/{:z;N;/motcle2$/!bz;s/\n/ /g;s/motcle2/\n&/}'
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

2

vanhell, le 20 mai 2009 à 10:53:25

Merci pour la réponse super rapide!
Je viens d'essaye mais j'obtiens cette erreur :

sed: The label /motcle1/{:z;N;/motcle2$/!bz;s/\n/ /g;s/motcle2/\n&/} is greater than eight characters.

Je suis sur un environement UNIX AIX, j'ai la commande sed mais pas gsed, peut être a cause de ça non?

Répondre à vanhell

3

jipicy, le 20 mai 2009 à 10:59:31

Essaie comme ça alors :

sed '
/motcle1/ {
:z
N
/motcle2$/ !b z
s/\n/ /g
s/motcle2/\n&/
}
'
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

4

vanhell, le 20 mai 2009 à 11:02:39

Comme ça plus d'erreurs mais uniquement les 2 premières lignes affichées :

texte texte texte texte texte
texte texte texte

Répondre à vanhell

5

jipicy, le 20 mai 2009 à 11:06:50

Bizarre chez moi ça marche bien :

[tmpfs]$ cat plop
texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte

[tmpfs]$ sed '
/motcle1/ {
:z
N
/motcle2$/ !b z
s/\n/ /g
s/motcle2/\n&/
}
' plop
texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte
motcle2
texte texte
texte

[tmpfs]$  
;-\ ??

Tu peux faire un copier/coller comme le mien de ce que tu as d'affiché dans ton terminal ?
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

6

vanhell, le 20 mai 2009 à 11:10:12

[test]$ cat sed.txt
texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte
[test]$ sed '
> /motcle1/ {
> :z
> N
> /motcle2$/ !b z
> s/\n/ /g
> s/motcle2/\n&/
> }
> ' sed.txt
texte texte texte texte texte
texte texte texte
[test]$

Répondre à vanhell

7

vanhell, le 20 mai 2009 à 11:20:47

Non en faite ça fonctionne presque, le fichier sur lequel je testé provenait de windows donc fin de ligne avec \r\n...

Avec le même fichier crééer directement sur le serveur j'obtiens maintenant ça :

texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte nmotcle2
texte texte
texte


C'est preque bon il y a un juste un bug juste avant le "motcle2" il a un un "n" au lieu d'un retour a la ligne, je ne sais pas ou est passé l'antislah XD
Bizare surtout que ça fonctionne chez toi...

Répondre à vanhell

8

jipicy, le 20 mai 2009 à 11:27:01

Bizarre effectivement ;-\

Par contre chez moi c'est du GNU/Linux et pas du AIX...

Essaies de supprimer "s/motcle2/\n&/" et refais un test.
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

9

vanhell, le 20 mai 2009 à 11:34:33

J'obtiens ceci :
$ sed '
> /motcle1/ {
> :z
> N
> /motcle2$/ !b z
> s/\n/ /g
> }
> ' sed.txt
texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte motcle2
texte texte
texte

Répondre à vanhell

10

jipicy, le 20 mai 2009 à 11:40:45

Essaye comme ça :

sed '
/motcle1/ {
:z
N
/motcle2$/ !b z
s/\n[^\(mocle2\)]/ /g
}
'
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

11

vanhell, le 20 mai 2009 à 11:49:43

Presque! de plus en plus pret lol

texte texte texte texte texte
texte texte texte
motcle1 exte texte exte exte texte texte
motcle2
texte texte
texte

le "t" en moins dans "mocle2" c'est fait expres?

Je pensais que c'était une faute de frappe mais en remmettant le t je n'ai plus aucun changement par rapport au fichier d'origine :

texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte

Répondre à vanhell

12

jipicy, le 20 mai 2009 à 11:54:11

Là je sèche :-((

Chez moi tout marche bien ;-\

Je parierai plus sur le fait que tu sois sur AIX, doit y avoir (je ne sais où) des interactions entre sed et le shell ;-\
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

13

jipicy, le 20 mai 2009 à 12:32:34

Tu peux toujours essayer avec "ed" :

[tmpfs]$ cat plop
texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte

[tmpfs]$ ed -s plop <<<$'/motcle1/,/motcle2/g/$/s/.$/& /g\n/motcle1/,/motcle2/-1j\nw'

[tmpfs]$ cat plop
texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte
motcle2
texte texte
texte
[tmpfs]$
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

14

vanhell, le 22 mai 2009 à 09:15:20

Rebonjour!
Non ça ne fonctionne pas sur cette machine avec ed, la shell est ksh ça vient surement de la.
Il faudrait trouver une solution avec awk ou perl...

Répondre à vanhell

15

lami20j, le 22 mai 2009 à 09:37:54

Salut,

$ cat fichier.txt
texte texte texte texte texte
texte texte texte
motcle1
texte texte
texte
texte texte texte
motcle2
texte texte
texte
$ perl -ne 's/\n/ / if /motcle1/../motcle2/;s/motcle2 /\nmotcle2\n/;print' fichier.txt
texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte
motcle2
texte texte
texte
106485010510997108

Répondre à lami20j

17

jipicy, le 22 mai 2009 à 09:45:10

Merci ;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

18

vanhell, le 22 mai 2009 à 10:31:11

Salut,
Merci ça fonctionne bien, même un peu trop lol j'explique :

$cat fictest
CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS,
ID_GRP_PERS, AGE_PERS
NB_ENF, MAX('GRP') AS MAXG
FROM TAB_PERS_GRP_PERS
WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT FROM ORACLE;


perl -ne 's/\n/ / if /SELECT/../FROM/;s/FROM /\nFROM\n/;print' fictest


CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS, ID_GRP_PERS, AGE_PERS NB_ENF, MAX('GRP') AS MAXG
FROM
TAB_PERS_GRP_PERS WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT
FROM
ORACLE;

Il faudrait que ça change juste entre SELECT et FROM donc ça c'est bon, mais la ça rajoute aussi un retour à la ligne après FROM et des retour à la ligne apres chaque mot de la dernière ligne (si ça peut aider pour ne pas prendre en compte "DISCONNECT FROM ORACLE" , les mots clés "SELECT" et "FROM" sont toujours en début de ligne.
Merci d'avance

Répondre à vanhell

19

jipicy, le 22 mai 2009 à 10:42:57

Essaye comme ça :

perl -ne 's/\n/ / if /SELECT/../^FROM/;s/^FROM /\nFROM /;print'
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

20

vanhell, le 22 mai 2009 à 10:52:32

Presque!
Ca fonctionne mais ça enleve toujours le retour a la ligne avant le "WHERE"

J'obtient ça :

CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS, ID_GRP_PERS, AGE_PERS NB_ENF, MAX('GRP') AS MAXG
FROM TAB_PERS_GRP_PERS WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT FROM ORACLE;

et il faudrait ça :

CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS, ID_GRP_PERS, AGE_PERS NB_ENF, MAX('GRP') AS MAXG
FROM TAB_PERS_GRP_PERS
WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT FROM ORACLE;

Répondre à vanhell

21

jipicy, le 22 mai 2009 à 11:00:38

Va falloir attendre lami20j, n'étant pas un grand spécialiste de Perl pour ma part, désolé ;-(

Sinon, j'ai ça avec "ed" (essaie on sait jamais) :

echo 'H
/SELECT/,/^FROM/g/$/s/.$/& /g
/SELECT/,/^FROM/-1j
,p' | ed -s fic
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

22

vanhell, le 22 mai 2009 à 11:37:19

Merci ça fonctionne sur la plupart des fichiers mais ne fait rien sur certain, exactement comme la solution que j'ai en awk (cf plus bas)
La solution en perl de lami20j fonctionne sur tous les fichiers mais malheuresement il reste un petit truc qui ne va pas (la suppresion du retour à la ligne avant le WHERE)

Ma solution en awk :

awk ' /^SELECT$/ { i=1 }; i==1 { if ( $0 ~ /^FROM$/) { print ligne; i=0} else { if (ligne == "") {ligne=$0} else {ligne=ligne" "$0} }} i==0 ' fichier

Répondre à vanhell

23

jipicy, le 22 mai 2009 à 11:48:00

mais ne fait rien sur certain,
On peut avoir un exempl(e|aire) de ces fameux fichiers ?
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

24

vanhell, le 22 mai 2009 à 12:04:53

En faite je viens de tester à l'instant, quand je lance la commande (celle avec ed) sur le fichier, une partie du fichier est bien transformé mais pas tout, donc j'ai copié une petite partie du fichier qui n'était pas transformé dans un autre fichier et quand je lance la commande sur ce nouveau fichier ça fonctionne.
Je ne peux pas copier tout le fichier ici il est trop gros, je peux te l'envoyer par mail?

Répondre à vanhell

25

jipicy, le 22 mai 2009 à 12:16:01

Oui envoie à l'adresse dans mon profil.
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

26

lami20j, le 22 mai 2009 à 13:34:58

Salut,

Presque!
Oui, effectivement, mais la commande fait ce que tu as presque demandé.

Donc si tu veux plus de précision alors j'ai besoin de plus de précisions.
Il faudra donner exactement ta requête et dire ce que tu veux obtenir. 106485010510997108

Répondre à lami20j

27

jipicy, le 22 mai 2009 à 13:43:23

Re-

Ta commande (retouchée par bibi) :

perl -ne 's/\n/ / if /SELECT/../^FROM/;s/^FROM /\nFROM /;print'
substitue les sauts de ligne par des espaces pour les ligne dans l'intervalle donné et par conséquent y compris celui de la ligne qui contient le motif "FROM" et ça donne :
CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS, ID_GRP_PERS, AGE_PERS NB_ENF, MAX('GRP') AS MAXG
FROM TAB_PERS_GRP_PERS [espace au lieu de saut de ligne] WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT FROM ORACLE;
Alors qu'il faudrait :
CONNECT TO ORACLE (&CONXORA);
CREATE TABLE ALIAS.TABLECREEE AS
SELECT ID_PERS, ID_GRP_PERS, AGE_PERS NB_ENF, MAX('GRP') AS MAXG
FROM TAB_PERS_GRP_PERS [un saut de ligne ici] 
WHERE DATE_DEB <= &DATE_FIN
AND (DATE_FIN IS NULL OR DATE_DEB > &DATE_FIN)
);
DISCONNECT FROM ORACLE;
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

28

lami20j, le 22 mai 2009 à 13:53:51

Hello bibi ;-))

Et ça?!

perl -ne 's/\n/ / if /SELECT/../^FROM/;s/^FROM /\nFROM /;s/WHERE/\nWHERE/;print'

Bon, faire tout dans une commande quand les choses se compliquent n'est pas le top.

Pour une solution fiable, peut être que la création d'un script s'impose.
On attends vanhell ou loudvig pour plus de précisions ;-) 106485010510997108

Répondre à lami20j

29

vanloudhellvig, le 22 mai 2009 à 14:12:24

Encore merci à vous deux ça fonctionne sur tous les fichiers avec perl contrairement à awk ou ed, je ne sais toujours pas pourquoi...
Merci lami20j et jipicy d'avoir passer du temps pour m'aider!

Répondre à vanloudhellvig

30

jipicy, le 22 mai 2009 à 15:46:14

J'ai bien reçu le fichier, mais j'ai beau triturer la commande "ed" dans tous les sens, je n'arriva pas à modifier toutes les occurrences voulues (uniquement la dernière), mais c'est un problème de syntaxe de "ed" ou une limitation ? J'avoue que je ne suis pas encore bien familiarisé avec sa syntaxe bien particulière, qui même si elle est proche de "sed" (ou l'inverse vu que "ed" était là avant), elle plus biscornue ;-((

Le principal c'est qu'on ait (enfin lami20j surtout) trouvé une solution.

Bon week-end.
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

31

vanhell, le 22 mai 2009 à 15:51:34

Oui pareil je ne comprend pas pourquoi ta solution et la mienne avec awk ne fonctionne pas a chaque fois...
Mais oui comme tu le dis le principal c'est que ça fonctionne en perl.
Encore merci à vous deux et bon week end!

Répondre à vanhell

32

jipicy, le 22 mai 2009 à 16:17:47

Je reviens à la charge avec "sed", ça :

sed '
/SELECT/ {
    :z
    N
    /\nFROM/ !b z
    s/\n[^\(FROM\)]/ /g
}' perl2.txt
ça marche toujours pas ?
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

33

vanhell, le 22 mai 2009 à 16:50:06

Heu ça fonctionne à part que ça enlève la premiere le premier de caractere des champs SELECT sauf le premier, comme dans ta solution au post 10

Répondre à vanhell

34

jipicy, le 22 mai 2009 à 17:01:06

Toujours aussi bizarre ;-\

Chez moi avec ton fichier perl2.txt ça marche très bien ;-\
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

35

 vanhell, le 22 mai 2009 à 17:11:30

Oui j'avais essayé chez moi aussi le code avec sed sur ubuntu ça fonctionnait mais la sur AIX avec ksh ça na fonctionne pas.
Pas grave le principal c'est d'avoir trouver une autre solution.

Répondre à vanhell

16

jipicy, le 22 mai 2009 à 09:44:23

Et comme ça :

[tmpfs]$ echo 'H
/motcle1/,/motcle2/g/$/s/.$/& /g
/motcle1/,/motcle2/-1j
.
w' | ed -s plop
???

Édit : C'est plus simple comme ça...

Version affichage :
$ echo '/motcle1/,/motcle2/g/$/s/.$/& /g
/motcle1/,/motcle2/-1j
,p' | ed -s plop
texte texte texte texte texte
texte texte texte
motcle1 texte texte texte texte texte texte
motcle2
texte texte
texte
Version écriture :
$ echo '/motcle1/,/motcle2/g/$/s/.$/& /g
/motcle1/,/motcle2/-1j
w' | ed -s plop
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy