比方說,我們有兩個文件(相同的尺寸爲M * N矩陣),與欄目:如何交錯兩個文件的列?
A1, A2, A3, A4, ..., An
和
B1, B2, B3, B4, ..., Bn
預期結果將是:
A1, B1, A2, B2, A3, B3, A4, B4, ..., An, Bn
哪有這樣做?我想有一些awk單線程,但我一直沒有能夠建立正確的...
比方說,我們有兩個文件(相同的尺寸爲M * N矩陣),與欄目:如何交錯兩個文件的列?
A1, A2, A3, A4, ..., An
和
B1, B2, B3, B4, ..., Bn
預期結果將是:
A1, B1, A2, B2, A3, B3, A4, B4, ..., An, Bn
哪有這樣做?我想有一些awk單線程,但我一直沒有能夠建立正確的...
這樣的事情在我的測試中似乎確定,考慮到這兩個文件具有相同數量的行和字段=同一陣列尺寸:
$ 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
這個和Ed Morton的答案都能正常工作(如問題所示,文件是m * n個矩陣,而不僅僅是一行)。由於詳細的解釋,將此答案標記爲正確。 – Elabore
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
如果作爲輸入提示,你只使用一個單一的每個輸入的行,那麼按記錄處理可能比按字段處理更容易。您可以通過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=", "}
使用tr
和rs
(reshape 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
榮譽分隔符用於輸入和輸出,請參閱手冊頁。我故意留下了逗號。
貼 + 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
重要的是指出這個解決方案依賴於'bash'進程替換。 OP沒有指出他們正在使用的外殼或操作系統。 – ghoti
@ghoti,在Unix shell中添加* – RomanPerekhrest
進程替換不是ash,dash,csh,tcsh的一部分。我相信bash的符號是由AT&T ksh共享的(但我認爲不是pdksh),但是這個非POSIX功能在zsh中的工作方式不同,我不知道它是否支持魚。那麼「* for Unix shell *」是什麼意思? – ghoti
你嘗試過什麼?我們大多數人都很樂意幫助你改進自己的技藝,但不願意擔任短期無償編程人員。在[MCVE](http://stackoverflow.com/help/mcve)中向我們展示您的工作,您期待的結果以及您獲得的結果,我們將幫助您弄清楚。 – ghoti