題 Linux / Unix命令用分隔符連接N行輸入?


在Linux / Unix命令行中,我想轉向:

A
B
C
A
B
C
.
.
.

進入這個:

A,B,C
A,B,C
...

是否有一個簡單的內置命令來執行此操作,或者這需要潛入Awk,Perl等?


4
2018-03-29 16:39


起源




答案:


不知道這樣的內置。運用 Bash 您可以:

while read a && read b && read c ; do echo $a,$b,$c ; done < file

7
2018-03-29 16:48



如果你只有5行,你可能不想丟失第4行和第5行只是因為你沒有第6行。 - musiphil


這太可怕了,肯定是這樣的

tr \\n ' '

會做同樣的事情嗎?

所以對於例如加入文件的行 file_lines 使用

cat file_lines | tr \\n ' '

4
2018-02-17 09:55



看起來他並不希望所有這一切都在一條線上。 - l0b0
究竟。引用問題陳述,這將產生一條單行,其中包含所有內容(A B C A B C A B C A B C A B C ...),這不是所要求的。 - Alan Krueger


如果你很幸運,輸入中沒有空格,那麼

xargs -n3 echo |tr ' ' ,

會這樣做的。


2
2017-08-20 00:44



這是一個很好的建議。十分優雅。如果你有空格,請使用 xargs -l3 - xpt
該 tr 如果輸入中有空格,則會破壞輸出,即使是 xargs -l - Steven Taschuk
好吧那麼,我會提供自己的答案。 - xpt


POSIX解決方案 pr

pr -3 -a -t -s, file

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html


1
2018-05-19 02:19





這是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

在您的情況下,您可以使用這樣的功能:

njoin("/path/to/file", n=3, linesuffixe=",")

0
2018-06-14 20:23





您提供的示例有3行,但您的主題強調 ñ 輸入行,所以我假設3行僅用於說明目的,你真正需要的是那些 ñ 輸入行,可能多達10個,這反過來使得接受的bash腳本難以管理。

有一些簡單的內置命令可以執行此操作,而無需深入了解Awk或Perl。這是一種方式。

一,樣本輸入,

 $ 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

現在假設 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

我相信這應該接近你想要的。


0
2017-08-20 01:35





GNU / Linux命令將每組N行合併為一行是a paste 命令。 這不是內置命令,但它是coreutils的一部分,因此默認安裝它。

您的示例將如下所示:

user@host:~$ cat ABC.text
A
B
C
A
B
C

user@host:~$ cat ABC.text | paste - - - -d,
A,B,C
A,B,C

如果有的話  輸入行,然後最後一行輸出將是不完整的:

user@host:~$ cat ABC.text | head -5 | paste - - - -d,
A,B,C
A,B,

如果我們想要將行分組不是3,而是2:

user@host:~$ cat ABC.text | paste - - -d,
A,B
C,A
B,C

如果有的話  輸入行,然後最後一行輸出將是不完整的:

user@host:~$ cat ABC.text | head -5 | paste - - -d,
A,B
C,A
B,

如你所見,你正在盡可能多地投入 - (在這種情況下指的是 stdin),作為要合併為一行的行數。如果輸入行數不足,則最後一個關節線將不完整。

要處理組中的大量行,您只需添加更多行 -

看到 man paste 了解更多信息。


讓我們看一個真實的例子:輸出 iwlist 命令。首先,我們只選擇 ESSID 輸出中的行(並且讓我們添加一些混淆;這部分不會改變,因此可以忽略):

user@host:~$ iwlist wifi scanning | grep "ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/\1XX:XX:XX:XX\3/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/\1\2......\"/g" 
ESSID:"DIREC......"
ESSID:"MGTS_......"
ESSID:"the g......"
ESSID:"MGTS_......"
ESSID:"sunny......"
ESSID:"beeli......"
ESSID:"Beeli......"
ESSID:"HG530......"
ESSID:"MGTS_......"
ESSID:"Home_......"

如果以後我們要添加 地址 到我們的輸出,然後輸出將變為交替線 地址 和 ESSID

user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/\1XX:XX:XX:XX\3/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/\1\2......\"/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_......"

要將每兩行合併為一行,請添加 | paste - -

user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/\1XX:XX:XX:XX\3/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/\1\2......\"/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_......"

如果以後我們要添加一個 協議比特率 和 頻率,然後輸出將是5行eash的組列表(地址ESSID協議頻率,和 比特率)。

user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID\|Protocol\|Rates\|Frequency" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/\1XX:XX:XX:XX\3/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/\1\2......\"/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

要將每5行合併為一行,只需添加即可 | paste - - - - -

user@host:~$ iwlist wifi scanning | grep "Cell\|ESSID\|Protocol\|Rates\|Frequency" | sed -e 's/^ *//g' -e 's/\(ess: ...\)\(.*\)\(...$\)/\1XX:XX:XX:XX\3/g' -e "s/\(ESSID:\"\)\(.....\)\(.*\"\)/\1\2......\"/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


0
2018-02-15 23:14