Awk 合并多个文件并基于每列将输出拆分为多个文件(第2篇文章)
我有许多行和列格式完全相同的csv文件。在下面的示例中,我只提供了2个文件作为输入,但我有很多具有相同特征的文件 目的是为每个输入文件执行以下操作: 取第1、2和3行中的值 第一个文件中的示例Awk 合并多个文件并基于每列将输出拆分为多个文件(第2篇文章),awk,Awk,我有许多行和列格式完全相同的csv文件。在下面的示例中,我只提供了2个文件作为输入,但我有很多具有相同特征的文件 目的是为每个输入文件执行以下操作: 取第1、2和3行中的值 第一个文件中的示例 6174 15 3 然后,打印第4行到第6行的第一列 对所有输入文件执行相同的过程,并输出一个包含所有读取文件的所有信息的文件 处理完所有文件和第一列后。对其余列执行相同的操作 最后,创建的总文件输出将为4个文件,因为每个文件中有4列 输入1 输入2 使用下面的代码,我得到了所需的4个输出文件,尽管文件
6174
15
3
然后,打印第4行到第6行的第一列
对所有输入文件执行相同的过程,并输出一个包含所有读取文件的所有信息的文件
处理完所有文件和第一列后。对其余列执行相同的操作
最后,创建的总文件输出将为4个文件,因为每个文件中有4列
输入1
输入2
使用下面的代码,我得到了所需的4个输出文件,尽管文件3-4不如spected好,因为在第一行中有空值,并且我的代码没有按预期工作。此外,我还有一个问题,就是如何在每个文件的第3行中获得正确的值。。我得到的是我们,而不是一个数字
输出文件1
输出文件2
输出文件3
输出文件4
使用的代码
代码工作得很好,合并csv文件并输出4个文件重新查询,但是文件3-4有一个问题,当有空值时
for f in *.csv ; do
awk -F, 'NR==1 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
awk -F, 'NR==2 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
awk -F, 'NR==3 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
sed -i 's/\r$//' a-"$f"
for i in seq $(1...4); do
awk -F, 'NR>=4{f=1} f{print '"$""$i"'} f==6{exit}' "$f" > "a""$i"-"$f"
cat a-"$f" a"$i""-""$f" >> t"$i"
sed -i 's/\r$//' t"$i"
done
for i in seq $(1...4); do
awk -v RS= -v OFS=',' -v ORS='\n' '{$1=$1}1' t"$i" > file"$i".csv
done
done
rm -f ./a* ./t*
感谢您对GNU awk提供的ENDFILE和自动处理多个打开文件的帮助,并假设您发布的示例输出显示文件3和文件4的字段数均大于文件1和文件2是一个错误:
$ cat tst.awk
BEGIN { FS=OFS=","; numHdrFlds=3 }
FNR <= numHdrFlds {
gsub(/[^0-9]/,"")
hdr = (FNR==1 ? "" : hdr OFS) $0
next
}
{
for (i=1; i<=NF; i++) {
data[i] = (FNR==(numHdrFlds+1) ? "" : data[i] OFS) ($i)+0
}
}
ENDFILE {
for ( fileNr=1; fileNr<=NF; fileNr++ ) {
print hdr, data[fileNr] > ("outputFile" fileNr)
}
}
有趣的是,您没有在脚本有问题的地方发布输入文件。@Ed先生,已更新输入文件和代码,我使用shellcheck.net网站尝试改进代码。您好,karakfa,输入文件中的问题仅在存在空值时出现,如。。那么代码就不能正常工作了,至少应该是输入文件中的0,0…@OXXO仅供参考,如果你想联系的是我,我看不到带有@Mr Ed任何变体的消息。你必须使用标记@EdMorton才能让我看到它们。@EdMorton非常感谢你的代码,不客气。不过,艾德先生也不会引起我的注意。当我们已经在交谈时,请使用@EdMorton与我联系并称呼我。请使用Ed并放下Mr。
6174,15,3,1.6,1.7,1.8
6176,17,5,1.6,1.5,1.3
6174,15,3,19.5,23.2,26.5
6176,17,5,18.6,23.5,26.8
6174,15,3,0,0,28.3,27.0
6176,17,5,0,0,19.7,19.2
6174,15,3,0,0,27.0,25.4
6176,17,5,0,0,19.2,18.5
for f in *.csv ; do
awk -F, 'NR==1 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
awk -F, 'NR==2 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
awk -F, 'NR==3 {n=split($NF,f," ");print f[n]}' "$f" >> a-"$f"
sed -i 's/\r$//' a-"$f"
for i in seq $(1...4); do
awk -F, 'NR>=4{f=1} f{print '"$""$i"'} f==6{exit}' "$f" > "a""$i"-"$f"
cat a-"$f" a"$i""-""$f" >> t"$i"
sed -i 's/\r$//' t"$i"
done
for i in seq $(1...4); do
awk -v RS= -v OFS=',' -v ORS='\n' '{$1=$1}1' t"$i" > file"$i".csv
done
done
rm -f ./a* ./t*
$ cat tst.awk
BEGIN { FS=OFS=","; numHdrFlds=3 }
FNR <= numHdrFlds {
gsub(/[^0-9]/,"")
hdr = (FNR==1 ? "" : hdr OFS) $0
next
}
{
for (i=1; i<=NF; i++) {
data[i] = (FNR==(numHdrFlds+1) ? "" : data[i] OFS) ($i)+0
}
}
ENDFILE {
for ( fileNr=1; fileNr<=NF; fileNr++ ) {
print hdr, data[fileNr] > ("outputFile" fileNr)
}
}
$ awk -f tst.awk file1 file2
$ for i in outputFile*; do echo "$i"; cat "$i"; echo "---"; done
outputFile1
6174,15,3,1.6,1.7,1.8
6176,17,5,1.6,1.5,1.3
---
outputFile2
6174,15,3,19.5,23.2,26.5
6176,17,5,18.6,23.5,26.8
---
outputFile3
6174,15,3,0,28.3,27
6176,17,5,0,19.7,19.2
---
outputFile4
6174,15,3,0,27,25.4
6176,17,5,0,19.2,18.5
---