Come posso "unire" i pattern in un'unica riga?


10

Sto facendo grep e sed e ottengo 2 righe di un file che mi interessano. Come posso ottenere queste righe in una singola riga che termina con il carattere di nuova riga?
Ora sto ottenendo:

pattern1  
pattern2  

Vorrei ottenere pattern1 pattern2 \n


1
Puoi condividere più dati di esempio?
slm

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

Incolla è lo strumento per il lavoro, se si intende unire più righe di output in una sola.
slm

qualche strumento specifico? Come pensi di farlo?
Braiam,

Risposte:


7

paste:

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

Che dice: "leggi una riga da stdin (la prima -), leggi un'altra riga da stdin (la seconda -), quindi uniscili con uno spazio"


una tecnica specifica per bash:

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

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


Che cosa è - -? Il comando è così?
Jim,

@Jim - sì, è corretto. Stanno dicendo pastecome vuoi che elabori l'input. 2 alla volta. Aggiungi altro da fare 3 alla volta. seq 10 | paste -d " " - - .
slm

6

Metterò tre versioni di metodi diversi in una riga

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

E ce ne sono molti altri.


La trsoluzione inghiottirà la nuova riga finale, quindi potresti voler aggiungere ; echoa quella
glenn jackman

@glennjackman ah giusto! Grazie per il suggerimento. Tuttavia, sei libero di modificare la risposta. Mi mancava un po '!
Valentin Bajrami,

2

puoi farlo usando lo script della shell o nella riga di comando, inserisci l'output del comando in una variabile e poi echo:

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

non quotata, la variabile è anche soggetta all'espansione del nome file, quindi se nel risultato sono presenti caratteri glob (come *o ?), i valori possono cambiare.
Glenn Jackman,

@glennjackman, grazie per averlo menzionato, come possiamo risolvere questo problema?
Nidal,

@Networker non usando i backtick ma $()invece .. e usando printfprintf '%s\n' "$x"
Valentin Bajrami il

Mi aspetto che printf '%s\n' "$x"NON rimuoverà la newline "interna".
Glenn Jackman,

2

Con sed, puoi farlo:

<your previous commands> | sed '{N; s/\n/ /}'
  • N;dice seddi aggiungere la riga successiva nello spazio del motivo, quindi ora sedsta lavorando con entrambe le linee.
  • s/\n/ / sostituisce il carattere di nuova riga con uno spazio, "unendo" le due linee insieme.

2

Un modo semplice, pipe output a xargs:

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

Funziona solo con piccoli output, perché è limitato da un massimo di caratteri per riga di comando. Il valore più grande dipende dal sistema, è possibile ottenere questo valore utilizzando getconf ARG_MAX.


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

IFS sarà felice di mangiarlo se lo desideri.


-1

avvolgi il tuo sed / grep in backtick

quando il tuo comando originale era:

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

il tuo nuovo comando sarebbe:

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

Non inserisce gli spazi tra le linee, ma puoi sempre virare su un'altra sed pipe:

 | sed 's/$/ /'

1
Uh, no. Ciò eseguirà l'output del comando sed.
Glenn Jackman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.