Comment puis-je «fusionner» des motifs sur une seule ligne?


10

Je fais grep et sed et j'obtiens 2 lignes d'un fichier qui m'intéresse. Comment puis-je obtenir ces lignes sur une seule ligne se terminant par le nouveau caractère de ligne?
Maintenant je reçois:

pattern1  
pattern2  

Je voudrais obtenir pattern1 pattern2 \n


1
Pouvez-vous partager davantage d'exemples de données?
slm

Utilisation printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'
Valentin Bajrami

Le collage est l'outil pour le travail, si vous avez l'intention de fusionner plusieurs lignes de sortie en une seule.
slm

un outil spécifique? Comment comptez-vous y parvenir?
Braiam

Réponses:


7

paste:

{...pipeline...} | paste -d " " - -

Cela dit: "lire une ligne de stdin (le premier -), lire une autre ligne de stdin (le second -), puis les joindre avec un espace"


une technique spécifique à bash:

$ x=$(grep -o pattern. test.txt)
$ echo "$x"
pattern1
pattern2
$ mapfile -t <<< "$x"
$ echo "${MAPFILE[*]}"
pattern1 pattern2

réf: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile


Qu'est-ce que c'est - -? La commande est-elle comme ça?
Jim

@Jim - oui c'est vrai. Ceux-ci indiquent pastecomment vous souhaitez qu'il traite l'entrée. 2 à la fois. Ajoutez-en plus pour faire 3 à la fois. seq 10 | paste -d " " - - .
slm

6

Je vais mettre trois versions différentes méthodes d'affilée

AWK

printf %s\\n pattern1 pattern2 | awk -vRS="\n" -vORS=" " '1; END {print RS}'

SED

printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'

TR

printf %s\\n pattern1 pattern2 | tr '\n' ' '; echo

Et il y en a beaucoup plus.


La trsolution engloutira la nouvelle ligne de fin, donc vous voudrez peut-être ajouter ; echoà celle-ci
glenn jackman

@glennjackman ah à droite! Merci pour l'astuce. Vous êtes cependant libre de modifier la réponse. J'ai raté ce morceau!
Valentin Bajrami

2

vous pouvez le faire en utilisant le script shell ou en ligne de commande, mettez simplement la sortie de la commande dans une variable puis echoelle:

# x=$(grep -e "pattern1\|pattern2" test)
# printf '%s\n' "$x"
pattern1 pattern2

sans guillemets, la variable est également soumise à l'expansion du nom de fichier, donc si vous avez des caractères globaux (comme *ou ?) dans le résultat, les valeurs peuvent changer.
glenn jackman

@glennjackman, merci de le mentionner, comment pouvons-nous résoudre ce problème?
Nidal

@Networker en n'utilisant pas de backticks mais à la $()place .. et en utilisant printfprintf '%s\n' "$x"
Valentin Bajrami

Je m'attends à ce que printf '%s\n' "$x"cela ne supprime PAS la nouvelle ligne "interne".
glenn jackman

2

Avec sed, vous pouvez faire ceci:

<your previous commands> | sed '{N; s/\n/ /}'
  • N;indique sedd'ajouter la ligne suivante dans l'espace de motif, donc sedtravaille maintenant avec les deux lignes.
  • s/\n/ / remplace le caractère de nouvelle ligne par un espace, "fusionnant" les deux lignes ensemble.

2

Un moyen simple de diriger la sortie vers xargs:

$ echo -e 'a\nb' | xargs
a b

Cela ne fonctionne qu'avec de petites sorties, car il est limité par le nombre maximum de caractères par ligne de commande. La plus grande valeur dépend du système, vous pouvez obtenir cette valeur en utilisant getconf ARG_MAX.


1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS se fera un plaisir de le manger si vous le souhaitez.


-1

envelopper votre sed / grep dans des crochets

lorsque votre commande d'origine était:

grep -i 'foo' mylog.log | sed 's/bar/baz/gi'

votre nouvelle commande serait:

`grep -i 'foo' mylog.log | sed 's/bar/baz/gi'`

N'obtient pas les espaces entre les lignes, mais vous pouvez toujours virer de bord sur un autre tuyau sed:

 | sed 's/$/ /'

1
Euh non. Cela exécutera la sortie de la commande sed.
glenn jackman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.