Você precisaria de uma implementação de grep que não apenas pudesse imprimir partes das linhas (como seu grep com sua opção -o para imprimir somente o que corresponde à linha onde há uma correspondência), mas também partes das linhas várias vezes .
pcregrep é um deles:
pcregrep -o1 -o2 --om-separator=' ' '(\S+)\s*(?=(\S+))'
Aqui, -o2 imprime algo que não corresponde por si só, algo que é correspondido apenas a um operador antecipado ( (?=...) ), por isso pcregrep continuará a procurar mais correspondências a partir do final da palavra saída por -o1 .
\s corresponde aos caracteres de espaçamento (vertical ou horizontal), portanto, palavras nesse caso são sequências de caracteres sem espaçamento.
Em vez disso, você pode usar awk :
awk '{for (i=1; i<NF; i++) print $i, $(i+1)}'
Para awk , palavras são seqüências de caracteres não vazios (espaçamento horizontal), em algumas implementações limitadas a SPC e TAB.
Se você quiser considerar line. como duas palavras separadas: line e . , você pode usar a implementação GNU de awk que suporta a definição de campos com base em padrões como:
gawk -v FPAT='[[:alnum:]]+|[[:punct:]]+' '{for (i=1; i<NF; i++) print $i, $(i+1)}'
Onde palavras são definidas como sequências de caracteres alfanuméricos ou sequências de caracteres de pontuação.