Order:479959,60=20130624-09:45:02.046|35=D|11=884|38=723|21=1|1=30532|10=085|59=0|114=Y|56=MBT|40=1|43=Y|100=MBTX|55=/GCQ3|49=11342|54=1|8=FIX.4.4|34=388|553=2453|9=205|52=20130624-09:45:02.046|
Order:24780,100=MBTX|43=Y|40=1|34=388|553=2453|52=2013062409:45:02.046|9=205|49=11342|54=1|8=FIX.4.4|55=/GCQ3|11=405|35=D|60=20130624-09:45:02.046|56=MBT|59=0|114=Y|10=085|21=1|38=470|1=30532|
Order:799794,55=/GCQ3|49=11342|54=1|8=FIX.4.4|34=388|553=2453|9=205|52=2013062409:45:02.046|40=1|43=Y|100=MBTX|38=350|21=1|1=30532|10=085|59=0|114=Y|56=MBT|60=20130624-09:45:02.046|35=D|11=216|
Order:72896,11=735|35=D|60=2013062409:45:02.046|56=MBT|59=0|114=Y|10=085|1=30532|38=17|21=1|100=MBTX|43=Y|40=1|553=2453|9=205|52=20130624-09:45:02.046|34=388|8=FIX.4.4|54=1|49=11342|55=/GCQ3|
Je veux obtenir le numéro après 38=
et le nombre après 11=
qui devrait être renommé Clientid
La sortie doit être: -
Orderid-479959 38= 723 Clientid=884
Orderid-24780 38= 470 Clientid=405
Orderid-799794 38= 350 Clientid=216
Orderid-72896 38= 17 Clientid=735
Toute aide serait appréciée.
Vous pouvez utiliser
sed -nr 's/Order:([0-9]+),.*[,\|]38=([0-9]+)[,\|].*/Orderid-\1 38= \2/p' file | tee file2
Alors
sed -nr 's/.*[,\|]11=([0-9]+)[,\|].*/Clientid=\1/p' file | tee file3
Alors
paste -d ' ' file2 file3
Vous obtenez votre sortie sur stdout - redirigez à votre guise.
Je ne peux pas l'avoir sur une seule ligne (bien que quelqu'un peut évidemment ) puisque le 11=
et 38=
les champs peuvent être dans l'un ou l'autre ordre - je dois lire le fichier deux fois. Vous pouvez l'intégrer dans un script comme celui-ci:
#!/bin/bash
sed -nr 's/Order:([0-9]+),.*[,\|]38=([0-9]+)[,\|].*/Orderid-\1 38= \2/p' "$1" > file2
sed -nr 's/.*[,\|]11=([0-9]+)[,\|].*/Clientid=\1/p' "$1" > file3
paste -d ' ' file2 file3 > outfile
rm file2 file3
(cela nettoie les fichiers que nous écrivons dans le processus et écrit la sortie finale dans un fichier outfile
)
chmod u+x script
./script file
file2
et file3
dans le script si vous avez des fichiers existants avec ces noms dans le répertoire courant!s/old/new
remplacez old
par new
-r
utiliser ERE-n
n'imprime pas tant que nous ne le demandons pas (cela va simplement supprimer les lignes vides)[,\|]
rencontre ,
OR littéral |
([0-9]+)
quelques chiffres à sauvegarder pour plus tard\1
référence arrière au modèle enregistrétee
écrivez dans un fichier et imprimez sur stdout aussi pour pouvoir le vérifier> somefile
redirige la sortie vers somefile
au lieu de stdoutpaste -d ' ' file2 file3
collez les colonnes du fichier3 après les colonnes du fichier2 en utilisant un espace comme délimiteur.rm file2 file3
supprimer le fichier2 et le fichier3Un liners n'est pas toujours sympa:
$ sed 's/[|,]\(11=[^|]*\).*\(|38=[^|]*|\).*/\2\1|/; s/Order:\([0-9]*\).*|38=\([0-9]*\).*|11=\([0-9]*\)|.*/Orderid-\1 38= \2 Clientid=\3/' foo
Orderid-479959 38= 723 Clientid=884
Orderid-24780 38= 470 Clientid=405
Orderid-799794 38= 350 Clientid=216
Orderid-72896 38= 17 Clientid=735
s/old/new/
Remplacez old
par new
[|,]
Correspond à |
Ou ,
\(11=[^|]*\)
correspond à n'importe quel nombre de caractères sauf |
après 11=
et enregistre 11=whatever
pour une utilisation ultérieure sous \1
.*
N'importe quel nombre de caractères\(|38=[^|]*|\)
enregistrer |38=whatever|
pour une utilisation ultérieure sous \2
\2\1|
Rétro-références en remplacement (cela rend les champs cohérents afin que nous puissions les traiter dans la prochaine commande);
Sépare les commandes, comme dans le ShellOrder:\([0-9]*\).*|38=\([0-9]*\).*|11=\([0-9]*\)|.*
correspond à ce modèle (maintenant nous l'avons nettoyé) en enregistrant à nouveau les pièces que nous voulons réutiliser dans \(parentheses\)
Orderid-\1 38= \2 Clientid=\3
Par \1
\2
Et \3
Renvois aux numéros que nous avons enregistrés avec \(\)
En une ligne:
Perl -a -F'[:|,]' -lne 'next if $_ =~ /^$/;printf("%sid-%s ",$F[0],$F[1]);foreach(@F){$t=$_ if $_ =~ "38=";$id=$_ if $_ =~ "11="};$id =~s/11=//;printf("%s Clientid=%s\n",$t,$id)' input.txt
Ou comme script:
#!/usr/bin/env Perl
use strict;
use warnings;
open(my $fh,'<',$ARGV[0]) or die $!;
while(my $line = <$fh>){
next if $line =~ /^$/;
my @words = split /[:|,]/,$line;
printf("%sid-%s ",$words[0],$words[1]);
my $t;
my $id;
foreach my $Word (@words){
$t = $Word if $Word =~ "38=";
$id=$Word if $Word =~ "11=";
$id =~ s/11=// if length($id);
}
printf("%s Clientid=%s\n", $t ,$id);
}
close($fh) or die $!;
Résultats de test:
$ ./parse_orders.pl ./input.txt
Orderid-479959 38=723 Clientid=884
Orderid-24780 38=470 Clientid=405
Orderid-799794 38=350 Clientid=216
Orderid-72896 38=17 Clientid=735