2017-08-31 48 views
0

比方說,我們有兩個文件(相同的尺寸爲M * N矩陣),與欄目:如何交錯兩個文件的列?

A1, A2, A3, A4, ..., An 

B1, B2, B3, B4, ..., Bn 

預期結果將是:

A1, B1, A2, B2, A3, B3, A4, B4, ..., An, Bn 

哪有這樣做?我想有一些awk單線程,但我一直沒有能夠建立正確的...

+0

你嘗試過什麼?我們大多數人都很樂意幫助你改進自己的技藝,但不願意擔任短期無償編程人員。在[MCVE](http://stackoverflow.com/help/mcve)中向我們展示您的工作,您期待的結果以及您獲得的結果,我們將幫助您弄清楚。 – ghoti

回答

1

這樣的事情在我的測試中似乎確定,考慮到這兩個文件具有相同數量的行和字段=同一陣列尺寸:

$ cat file1 
a1,a2,a3 
a4,a5,a6 

$ cat file2 
b1,b2,b3 
b4,b5,b6 

$ awk 'NR==FNR{f1[FNR]=$0;next};{split(f1[FNR],ff1,",");split($0,ff2,","); \ 
for (f=1;f<=length(ff1);f++) printf ff1[f]","ff2[f](f!=length(ff1)?",":"\n")}' file1 file2 
a1,b1,a2,b2,a3,b3 
a4,b4,a5,b5,a6,b6 

快速解釋:
AWK讀取第一所述一個文件,然後該第二文件。
NR==FNR{f1[FNR]=$0;next}:讀取的第一個文件,並用的indeces建立一個數組F1 file1和內容的行數的整行$ 0

當第一文件完成,則代碼的其餘部分file2中的處理過程中執行:

split(f1[FNR],ff1,","):由於兩個文件的行數相同,因此通過使用逗號作爲分隔符將這些文件從file1(存儲在數組f1中)拆分爲新的數組ff1。

split($0,ff2,","):類似地,這將$ 0 = file2的當前記錄/當前行拆分爲名稱爲ff2的數組,使用逗號作爲分隔符。

for (f=1;f<=length(ff1);f++) printf ff1[f]","ff2[f](f!=length(ff1)?",":"\n")
通過從兩個FF1和FF2 FF1的數組元素(FF1具有FF2的相同的長度),並打印數據。這一個迭代。

(f!=length(ff1)?",":"\n"):這將打印逗號,,而我們還沒有達到陣列FF1/FF2結束,否則打印一個換行符\n

+1

這個和Ed Morton的答案都能正常工作(如問題所示,文件是m * n個矩陣,而不僅僅是一行)。由於詳細的解釋,將此答案標記爲正確。 – Elabore

2
awk ' 
    BEGIN { FS=OFS=", " } 
    NR==FNR { a[NR]=$0; next } 
    { 
     split(a[FNR],f) 
     for (i=1;i<=NF;i++) { 
      printf "%s%s%s%s", f[i], OFS, $i, (i<NF?OFS:ORS) 
     } 
    } 
' a.txt b.txt 
0

如果作爲輸入提示,你只使用一個單一的每個輸入的行,那麼按記錄處理可能比按字段處理更容易。您可以通過stdin讀取一個文件,並明確讀取其他文件。

作爲一個襯墊,這可能是這樣的:

awk 'BEGIN {ORS=RS=","} {print $1; getline < "f2"; print $1}' f1; echo 

爆發,方便閱讀與評論:

awk ' 
    BEGIN { ORS=RS="," }  # record separator is a comma! 
    { 
    print $1    # print a trimmed (1-field) record from the first file, 
    getline < "file2"  # then get the next record from the second file. 
    print $1    # print a record from the second file. 
    } 
' file1 
echo      # print a newline, since awk didn't. 

如果您希望自己的輸出有逗號後的空格您可以將BEGIN塊中的代碼替換爲:

BEGIN {RS=","; ORS=", "} 
0

使用trrsreshape a data array),如果有的話。如果沒有,請與當地的管理員交談或攻擊地球。首先,測試數據:

$ cat foo bar 
a1,a2,a3 
b1,b2,b3 

發送到tr更換,與空間:

$ cat foo bar | tr , ' ' 
a1 a2 a3 
b1 b2 b3 

和上rs用於調換:

$ cat foo bar | tr , ' ' | rs -T 
a1 b1 
a2 b2 
a3 b3 

終於到另一rs擠以前在一條線上:

$ cat foo bar | tr , ' ' | rs -T | rs 1 
a1 b1 a2 b2 a3 b3 

最後rs可替換爲tr \n' ' 'rs榮譽分隔符用於輸入和輸出,請參閱手冊頁。我故意留下了逗號。

0

+ TR + 的sed在Unix外殼招:

file1內容:


file2項內容:

B1, B2, B3, B4, B5, B6, B7 

paste <(tr ',' '\n' <file1) <(tr ',' '\n' <file2) | paste -s | sed 's/[[:space:]]\+/, /g' 

輸出:

A1, B1, A2, B2, A3, B3, A4, B4, A5, B5, A6, B6, A7, B7 
+1

重要的是指出這個解決方案依賴於'bash'進程替換。 OP沒有指出他們正在使用的外殼或操作系統。 – ghoti

+0

@ghoti,在Unix shell中添加* – RomanPerekhrest

+1

進程替換不是ash,dash,csh,tcsh的一部分。我相信bash的符號是由AT&T ksh共享的(但我認爲不是pdksh),但是這個非POSIX功能在zsh中的工作方式不同,我不知道它是否支持魚。那麼「* for Unix shell *」是什麼意思? – ghoti