0
votes

J'ai dossé avec 3 lignes comme suit. Utilisation de Linux Comment puis-je obtenir les variables divisées d'une ligne et l'ajouter à la même ligne

Utilisation de Linux, comment puis-je obtenir la sortie souhaitée ci-dessous pour l'entrée donnée. Fichier d'entrée: xxx pré>

Ma sortie doit être: p>

StringA1, stringB1| stringC1
StringA1, stringB1| stringD1
StringA1, stringB1| stringE1
StringA2, stringB2| stringC2
StringA2, stringB2| stringD2
StringA3, stringB3| stringC3
StringA3, stringB3| stringD3
StringA3, stringB3| stringE3
StringA3, stringB3| stringF3


5 commentaires

Pouvez-vous réparer le formatage de votre message afin qu'il soit plus facile de lire et de déterminer ce que vous voulez?


couper pourrait faire cela. awk aussi. Essayez quelque chose, alors nous pouvons vous aider.


Lorsque vous ne savez pas où commencer, vous pouvez expliquer quelles options que vous avez considérées, comme: "Je ne sais pas comment traiter les substrings que j'ai trouvés après avoir utilisé couper sur champ delim | ou sur ','. Peut-être que awk est possible, mais pour moi, c'est un nouvel outil complet. La meilleure option que je puisse utiliser l'utilisation d'un en boucle , Traitement d'une ligne à la fois. J'ai lu, que l'utilisation d'un tandis que la boucle donne une mauvaise performance. Maintenant je suis coincé, que dois-je faire? "


Vous mentionnez linux , où bash est la coque par défaut. Pourquoi voulez-vous ksh ?


Le fichier d'entrée contient-il les chaînes line1: / line2: / line3: ? Alternativement, quelle est la sortie exacte de CAT ?


3 Réponses :


1
votes

Lorsque vous faites une solution dans SED , il deviendra difficile à lire et à maintenir: xxx

explication: < BR> S /, / \ V / La plupart des , doivent être remplacés, mais pas celui de la chaîne de remplacement.
: a répéter la commande suivante (jusqu'à ce que ta ) alors qu'un remplacement est trouvé.
( BR> \ r Utilisez le marqueur Windows CR comme marqueur où nous voulons une nouvelle ligne lorsque vous avez terminé.
\ 1 Remplacez par la première chaîne mémorisée (par exemple stringa1, stressb1 ).
/ \ 1 \ 2 \ r \ 1 \ 3 / Remplacez le dernier , avec un marqueur de nouvelle ligne et le démarreur.
TA; répéter jusqu'à ce que tous les remplacements soient terminés.
s / \ v /, / g; restaurer les caractères , .
s / \ r / \ n / g ' remplacez le nouveau marqueur de ligne avec une nouvelle ligne réelle.

Autres moyens utilise Awk et un tandis que la boucle . Pour un fichier volet, j'ai recommandé awk , vous voulez peut-être essayer ceci vous-même avant que quelqu'un affiche une réponse.


4 commentaires

Maintenant, c'est une utilisation intéressante de SED pour le problème. Bien que l'approche AWK est probablement l'outil pour le travail, l'utilisation de sed ici (ainsi que la bonne explication) garantit certainement l'UV.


REMARQUE: Vous devez toujours vous scinder Field1 , votre commande fournit la sortie de "Ligne1: Stringa1, Stringb1 | stringc1" , etc.


@ Davidc.Rankin J'ai fait la même hypothèse que MarkP l'a fait, testant avec Echo "Stringa1, Stringb1 | Stringc1, Stringd1, stress1" | sed .... . Ajouter 's / [^:]: //' peut aider si nécessaire.


Oui, je pensais ça. Vraiment étrange d'avoir les lignes dans la question avec la ligne ambiguë à l'avant qui ressemble à elle / peut ne pas être dans le fichier. Tant pis. Il est couvert. Encore une fois, bon travail en utilisant sed .



2
votes

Hypothèses:

  • Toutes les lignes ont au moins 3 champs
  • Les lignes ne contiennent pas la chaîne ligne #: (sinon nous devons simplement modifier le script proposé)

    échantillons de données: xxx

    one awk solution: xxx

    Où:

    • -f "[ |]" - Utilisez la virgule et le tuyau (, | ) en tant que délimiteurs d'entrée
    • pour (i = 3; i <= nf; i ++) - pour les champs 3 à la fin de la ligne (NF == Nombre de champs == Dernier champ)
    • {printf ...} - Imprimer 1st, 2e et ITH Champs

      résultats d'exécution ci-dessus: xxx


3 commentaires

Remarque: Vous devez toujours vous diviser Field1 , votre commande fournit la sortie de "Line1: Stringa1, Stringb1 | stringc1" , etc. (bien que Le reste de votre approche est correct, donc cela justifie toujours l'UV. Il semble que le problème était une surveillance.)


@ DAVIDC.RANKIN Voir mes hypothèses (NO 'Line n °:' dans le fichier actuel), mon fichier de données ( chat strings.dat ) et mon commentaire / question à l'op re: 'Line #: ' dans le fichier; Ce n'est pas clair (pour moi) si la ligne de la ligne des chaînes: «Faites partie du fichier ou de l'OP étiquetant simplement les lignes de la question; Si l'OP revient et dit 'Line #:' est dans le fichier alors c'est assez facile pour analyser


Gotcha, j'ai lu vos hypothèses, mais je ne l'ai pas enfoncée lorsque je dirigeai la sortie. Il a couvert de toute façon à ce stade.



0
votes

Pour produire votre sortie souhaitée, si vous divisez sur [ |] code>, vous devez supprimer davantage le début field1 em> avant de sortir les résultats. Il y a deux façons de faire cela. La première façon simplement divise tout field1 em> dans un tableau avec le fieldsep em> de '' code>, la seconde est avec une combinaison de substrat-substrat & longueur code>. Le premier est le moyen simple de le faire à l'aide de la commande Split () code>, par exemple xxx pré>

pour la seconde, vous pouvez supprimer divisé () Code> ci-dessus et remplacer arr [2] code> avec: p> xxx pré>

si votre fichier de données n'inclut pas "ligne [0-9] : " code> comme préfixe pour chaque ligne, vous pouvez inclure les éléments suivants comme votre printf code> pour gérer les cas: p> xxx pré>

les résultats sont les mêmes de toute façon, mais en utilisant divisé () code> serait la voie recommandée. p>

EXEMPLE UTILISATION / SORTIE STRUT> P>

La solution proposée AWK code> avec votre fichier de données (nommé fichier code> ajuster au besoin), vous pouvez simplement sélectionner-copier / coller-coller-coller dans un xterm avec le Fichier code> dans le répertoire actuel pour obtenir les résultats, par exemple P>

$ awk -F '[,|]' '{
>     split ($1, arr, / /)
>     for (i=3; i<=NF; i++) {
>         printf "%s,%s|%s\n", arr[2], $2, $i
>     }
> }' file
StringA1, stringB1| stringC1
StringA1, stringB1| stringD1
StringA1, stringB1| stringE1
StringA2, stringB2| stringC2
StringA2, stringB2| stringD2
StringA3, stringB3| stringC3
StringA3, stringB3| stringD3
StringA3, stringB3| stringE3
StringA3, stringB3| stringF3


1 commentaires

Ou ajouter : comme délimiteur d'entrée supplémentaire et champs de processus 2, 3 et 4-NF