Não conheça esse tipo de built-in. Usando Bash
, você pode:
while read a && read b && read c ; do echo $a,$b,$c ; done < file
Na linha de comando do Linux / Unix, quero ativar isso:
A
B
C
A
B
C
.
.
.
para isso:
A,B,C
A,B,C
...
Existe um comando embutido simples para fazer isso, ou isso requer mergulhar no Awk, no Perl, etc.?
Isso é horrível, certamente algo como
tr \n ' '
faria o mesmo?
Assim, por exemplo para juntar linhas do arquivo file_lines use
cat file_lines | tr \n ' '
Se você tiver a sorte de não ter espaços na entrada,
xargs -n3 echo |tr ' ' ,
faria isso.
Aqui está uma solução em python:
#!/usr/bin/python3
def njoin(filename, outfn="", n=3, linesuffix=" "):
if not outfn:
outfn = filename + ".join"
with open(filename) as infh, open(outfn, "w") as outfh:
nline = 0
for line in infh:
if nline % n != n-1:
line = line.rstrip() + linesuffix
outfh.write(line)
nline += 1
No seu caso, você pode usar a função assim:
njoin("/path/to/file", n=3, linesuffixe=",")
A amostra que você deu tem 3 linhas, mas seu tópico enfatiza linhas N de entrada, então eu diria que 3 linhas são apenas para propósitos de ilustração, e o que você realmente precisa é que N linhas de entrada, que podem ser superiores a 10, o que, por sua vez, torna esse script bash aceito incontrolável.
Existem comandos internos simples para fazer isso, sem mergulhar no Awk ou no Perl. Aqui está um jeito.
Primeiro, a entrada de amostra,
$ seq 12 | cat -n
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
Agora, suponha que N=4
:
N=4
$ seq 12 | cat -n | sed 's/$/,/' | xargs -l$N | sed 's/,$//'
1 1, 2 2, 3 3, 4 4
5 5, 6 6, 7 7, 8 8
9 9, 10 10, 11 11, 12 12
Eu acredito que deveria estar perto do que você está procurando.
O comando GNU / Linux para mesclar cada grupo de N linhas em uma linha é um comando paste
.
Este não é um comando interno, mas é parte do coreutils, por isso é instalado por padrão.
Seu exemplo terá a seguinte aparência:
user@host:~$ cat ABC.text
A
B
C
A
B
C
user@host:~$ cat ABC.text | paste - - - -d,
A,B,C
A,B,C
Se houver apenas linhas de entrada 5 , a última linha de saída ficará incompleta:
user@host:~$ cat ABC.text | head -5 | paste - - - -d,
A,B,C
A,B,
Se quisermos agrupar as linhas não por 3, mas por 2:
user@host:~$ cat ABC.text | paste - - -d,
A,B
C,A
B,C
Se houver apenas linhas de entrada 5 , a última linha de saída ficará incompleta:
user@host:~$ cat ABC.text | head -5 | paste - - -d,
A,B
C,A
B,
Como você pode ver, você está colocando quantos -
(que neste caso se refere a stdin
), como o número de linhas que você deseja mesclar em um. Se o número de linhas de entrada for insuficiente, a última linha de junção estará incompleta.
Para lidar com um número maior de linhas em um grupo, você só precisa adicionar mais -
.
Veja man paste
para informações adicionais.
Vejamos um exemplo real: saída do comando iwlist
. Primeiro, vamos escolher apenas as linhas ESSID da saída (e vamos adicionar um pouco de ofuscação; essa parte não vai mudar, então pode ser ignorada):
user@host:~$ iwlist wifi scanning | grep "ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/XX:XX:XX:XX/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/......\"/g"
ESSID:"DIREC......"
ESSID:"MGTS_......"
ESSID:"the g......"
ESSID:"MGTS_......"
ESSID:"sunny......"
ESSID:"beeli......"
ESSID:"Beeli......"
ESSID:"HG530......"
ESSID:"MGTS_......"
ESSID:"Home_......"
Se mais tarde quisermos adicionar endereços à nossa saída, então a saída se transformará em linhas alternadas com endereços e ESSID .
user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/XX:XX:XX:XX/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/......\"/g"
Cell 01 - Address: 12:XX:XX:XX:XX:7A
ESSID:"DIREC......"
Cell 02 - Address: 70:XX:XX:XX:XX:32
ESSID:"MGTS_......"
Cell 03 - Address: E0:XX:XX:XX:XX:73
ESSID:"the g......"
Cell 04 - Address: 44:XX:XX:XX:XX:D2
ESSID:"MGTS_......"
Cell 05 - Address: 00:XX:XX:XX:XX:54
ESSID:"sunny......"
Cell 06 - Address: 00:XX:XX:XX:XX:7C
ESSID:"beeli......"
Cell 07 - Address: EC:XX:XX:XX:XX:DC
ESSID:"Beeli......"
Cell 08 - Address: C8:XX:XX:XX:XX:9F
ESSID:"HG530......"
Cell 09 - Address: CC:XX:XX:XX:XX:02
ESSID:"MGTS_......"
Cell 10 - Address: 28:XX:XX:XX:XX:E8
ESSID:"Home_......"
Para mesclar todas as duas linhas em uma, adicione | paste - -
:
user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/XX:XX:XX:XX/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/......\"/g" | paste - -
Cell 01 - Address: 12:XX:XX:XX:XX:7A ESSID:"DIREC......"
Cell 02 - Address: 70:XX:XX:XX:XX:32 ESSID:"MGTS_......"
Cell 03 - Address: E0:XX:XX:XX:XX:73 ESSID:"the g......"
Cell 04 - Address: 44:XX:XX:XX:XX:D2 ESSID:"MGTS_......"
Cell 05 - Address: 00:XX:XX:XX:XX:54 ESSID:"sunny......"
Cell 06 - Address: 00:XX:XX:XX:XX:7C ESSID:"beeli......"
Cell 07 - Address: EC:XX:XX:XX:XX:DC ESSID:"Beeli......"
Cell 08 - Address: C8:XX:XX:XX:XX:9F ESSID:"HG530......"
Cell 09 - Address: CC:XX:XX:XX:XX:02 ESSID:"MGTS_......"
Cell 10 - Address: 28:XX:XX:XX:XX:E8 ESSID:"Home_......"
Se mais tarde quisermos adicionar um Protocolo , Taxas de bits e Frequência , a saída será uma lista de grupos de 5 linhas eash ( endereço , ESSID , Protocolo , Frequência e Taxas de bits ).
user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID\|Protocol\|Rates\|Frequency" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/XX:XX:XX:XX/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/......\"/g"
Cell 01 - Address: 12:XX:XX:XX:XX:7A
ESSID:"DIREC......"
Protocol:IEEE 802.11gn
Frequency:2.412 GHz (Channel 1)
Bit Rates:144 Mb/s
Cell 02 - Address: 70:XX:XX:XX:XX:32
ESSID:"MGTS_......"
Protocol:IEEE 802.11bgn
Frequency:2.412 GHz (Channel 1)
Bit Rates:130 Mb/s
Cell 03 - Address: E0:XX:XX:XX:XX:73
ESSID:"the g......"
Protocol:IEEE 802.11bg
Frequency:2.412 GHz (Channel 1)
Bit Rates:54 Mb/s
Cell 04 - Address: 44:XX:XX:XX:XX:D2
ESSID:"MGTS_......"
Protocol:IEEE 802.11bgn
Frequency:2.412 GHz (Channel 1)
Bit Rates:130 Mb/s
Cell 05 - Address: 00:XX:XX:XX:XX:54
ESSID:"sunny......"
Protocol:IEEE 802.11bg
Frequency:2.427 GHz (Channel 4)
Bit Rates:54 Mb/s
Cell 06 - Address: 00:XX:XX:XX:XX:7C
ESSID:"beeli......"
Protocol:IEEE 802.11bgn
Frequency:2.422 GHz (Channel 3)
Bit Rates:300 Mb/s
Cell 07 - Address: EC:XX:XX:XX:XX:DC
ESSID:"Beeli......"
Protocol:IEEE 802.11bgn
Frequency:2.437 GHz (Channel 6)
Bit Rates:108 Mb/s
Cell 08 - Address: C8:XX:XX:XX:XX:9F
ESSID:"HG530......"
Protocol:IEEE 802.11bgn
Frequency:2.447 GHz (Channel 8)
Bit Rates:108 Mb/s
Cell 09 - Address: CC:XX:XX:XX:XX:02
ESSID:"MGTS_......"
Protocol:IEEE 802.11bgn
Frequency:2.442 GHz (Channel 7)
Bit Rates:130 Mb/s
Cell 10 - Address: 28:XX:XX:XX:XX:E8
ESSID:"Home_......"
Protocol:IEEE 802.11bgn
Frequency:2.472 GHz (Channel 13)
Bit Rates:108 Mb/s
Para mesclar cada 5 linhas em uma, basta adicionar | paste - - - - -
.
user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID\|Protocol\|Rates\|Frequency" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/XX:XX:XX:XX/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/......\"/g" | paste - - - - -
Cell 01 - Address: 12:XX:XX:XX:XX:7A ESSID:"DIREC......" Protocol:IEEE 802.11gn Frequency:2.412 GHz (Channel 1) Bit Rates:144 Mb/s
Cell 02 - Address: 70:XX:XX:XX:XX:32 ESSID:"MGTS_......" Protocol:IEEE 802.11bgn Frequency:2.412 GHz (Channel 1) Bit Rates:130 Mb/s
Cell 03 - Address: E0:XX:XX:XX:XX:73 ESSID:"the g......" Protocol:IEEE 802.11bg Frequency:2.412 GHz (Channel 1) Bit Rates:54 Mb/s
Cell 04 - Address: 44:XX:XX:XX:XX:D2 ESSID:"MGTS_......" Protocol:IEEE 802.11bgn Frequency:2.412 GHz (Channel 1) Bit Rates:130 Mb/s
Cell 05 - Address: 00:XX:XX:XX:XX:54 ESSID:"sunny......" Protocol:IEEE 802.11bg Frequency:2.427 GHz (Channel 4) Bit Rates:54 Mb/s
Cell 06 - Address: 00:XX:XX:XX:XX:7C ESSID:"beeli......" Protocol:IEEE 802.11bgn Frequency:2.422 GHz (Channel 3) Bit Rates:300 Mb/s
Cell 07 - Address: EC:XX:XX:XX:XX:DC ESSID:"Beeli......" Protocol:IEEE 802.11bgn Frequency:2.437 GHz (Channel 6) Bit Rates:108 Mb/s
Cell 08 - Address: C8:XX:XX:XX:XX:9F ESSID:"HG530......" Protocol:IEEE 802.11bgn Frequency:2.447 GHz (Channel 8) Bit Rates:108 Mb/s
Cell 09 - Address: CC:XX:XX:XX:XX:02 ESSID:"MGTS_......" Protocol:IEEE 802.11bgn Frequency:2.442 GHz (Channel 7) Bit Rates:130 Mb/s
Cell 10 - Address: 28:XX:XX:XX:XX:E8 ESSID:"Home_......" Protocol:IEEE 802.11bgn Frequency:2.472 GHz (Channel 13) Bit Rates:108 Mb/s
EOT
Tags command-line linux unix