J'ai le bloc de données suivant qui continue indéfiniment horizontalement et verticalement avec des nombres négatifs uniquement dans les colonnes impaires:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
Et je veux les 2ème, 4ème et 6ème colonnes complètes (ou chaque colonne paire) et les signes moins uniquement à partir des 1ère, 3ème et 5ème (ou toutes les colonnes impaires), donc j'obtiens ceci:
- 2 4 - 9
3 - 5 - 11
Et finalement finir avec ceci:
-2 4 -9
3 -5 -11
J'ai donc besoin que les valeurs des colonnes paires soient inchangées et des colonnes impaires, s'il y a une valeur négative, conservez le - uniquement et s'il y a une valeur positive, jetez-la.
Existe-t-il un moyen de le faire avec awk / sed?
C'est à peu près autant que je reçois:
awk '{ for (i=2;i<=NF;i+=2) $i="" }1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing
sed
awk
Asfound
la source
la source
Réponses:
Voici une façon:
Le
awk
script parcourt toutes les colonnes impaires et définit leur valeur-
si elles sont négatives et vides sinon. Ensuite, lesed
supprime tous les espaces suivant un-
, puis remplace plusieurs espaces consécutifs par un seul. Notez que cela signifie que l'alignement sera rompu car certains champs auront deux caractères ou plus et d'autres en auront un. Ce ne sera pas un problème si vous travaillez avec des champs, ils ne sont tout simplement pas jolis.la source
Le
sed
chemin:Production:
La première expression tue la colonne de fin s'il y a un nombre impair de colonnes. Il le fait en recherchant 0 ou plusieurs paires
<number> <number>
, où le premier nombre peut être négatif.Edit: Une
sed
solution plus courte , inspirée de @mikeserv:La même chose avec
perl
:Une autre façon
perl
(probablement la plus propre):la source
Un
perl
:-an
diviser l'entrée en@F
tableauBEGIN{$,=" "}
définir un séparateur de champ de sortie sur un espacegrep{!($_%2)}0..$#F
obtenir tous les index pairs dans un@F
tableau, qui sont des index d'éléments impairsmap{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}
vérifier si l'élément impair commence par-
, puis ajouter-
à l'élément pair suivant, sinon ajouter un espacela source
Comme la réponse de @ terdon mais sans le sed:
la source
Une
python
solutionla source
Une
awk
solution simple basée sur les mathématiques :i=2
) au dernier champ (i<=NF
).$(i-1)
) par -1 ou 1.printf "%4s"
) et imprimez une nouvelle ligne de fin (print ""
).La seule mise en garde est que si vous avez un nombre impair de colonnes, le dernier champ n'affichera rien du tout. J'espère que c'est ce que vous attendez.Apparemment, c'est ce que vous attendez. :)(modifié pour fonctionner avec des valeurs décimales et pour rendre les conditions de boucle plus alignées avec la question tout en enregistrant 2 caractères.)
la source
Vous devez oublier complètement le négatif - laissez-le de côté. Vous souhaitez consolider deux champs - de gauche à droite. C'est très simple.
Remarquez comment j'évite toute référence au signe - lorsque l'entrée est traitée, l'automate n'accepte que des espaces ou des chiffres car il ne comprend rien d'autre - tout le reste est complètement ignoré et reste en place.
Lorsque vous spécifiez un
\{
intervalle de répétition numérique\}
pour une\(
sous - expression\)
, seule la dernière occurrence de cette expression est\1
référencée en retour. Vous pouvez donc simplement presser - ou tronquer - un intervalle de répétition aussi facilement. Et parce que nous pressons la répétition derrière le signe - s'il y en a un - la deuxième occurrence de ce motif suivra tout signe qui précédait le premier.Le comportement décrit ci-dessus est spécifié par POSIX pour toutes les applications compatibles BRE, mais très peu
sed
le font correctement. GNU lesed
fait.Enfin, les espaces sont juste pour rendre l'occurrence du motif régulière .
Bien sûr, cela ne fonctionnera jamais pour vous. Ou, probablement plus correctement, cela fonctionnera toujours pour vous, mais ne retournera aucun résultat. Comment pourrait-il si le motif est indéfini ?
la source