假设我们有两个文件(大小相同的m * n矩阵),其中包含列:
A1, A2, A3, A4, ..., An
和
B1, B2, B3, B4, ..., Bn
预期输出为:
A1, B1, A2, B2, A3, B3, A4, B4, ..., An, Bn
如何做到这一点?我想有一些awk单行,但我无法构建正确的单行...
答案 0 :(得分: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
答案 1 :(得分: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}
:读取第一个文件并创建一个数组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的数组元素(ff1具有相同的ff2长度)并从ff1和ff2打印数据。
(f!=length(ff1)?",":"\n")
:当我们没有到达数组ff1 / ff2的末尾时会打印逗号,
,否则会打印换行符\n
答案 2 :(得分: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=", "}
答案 3 :(得分:0)
使用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
尊重输入和输出的分隔符,请参阅手册页。我故意把逗号留下了。
答案 4 :(得分:0)
粘贴 + tr + sed Unix shell的技巧:
file1
内容:
A1, A2, A3, A4, A5, A6, A7
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
答案 5 :(得分:0)
使用awk
和paste
的另一种解决方案不会受到损害。
paste -d',' file1 file2 | awk -F ',' '{
z = ""
for (i=1; i <= NF/2; ++i){
x = i+(NF/2)
y = $i","$x
z = z","y
}
print substr(z,2,length(z))
}'
首先,paste -d',' file1 file2
将两个文件放在同一行索引下,并使用相同的字段分隔符= ,
合并它们。
然后,在awk
中,-F ','
以逗号作为字段分隔符,并遍历1/2个列索引i <= NF/2
,找到对应的列以交织x = i+(NF/2)
并使用两个值y = $i","$x
创建一个新的逗号分隔字符串。最后,将这些新字符串连接到一个空字符串z = z","y
中,并在循环之后(不包括第一个逗号print substr(z,2,length(z))
的情况下打印)。
我个人认为,这比以前使用awk
的某些解决方案更为明确。