我有一个文件,其中包含第1和第2列,包含项目代码和名称,然后从第3列到第12列,其中包含连续10天的消耗量。 现在我需要将其转换为10个不同的文件。在每个第1和第2列应该是相同的项目代码和项目名称,第3列将包含每天的消费量一天..
输入文件:
Code | Name | Day1 | Day2 | Day3 |...
10001 | abcd | 5 | 1 | 9 |...
10002 | degg | 3 | 9 | 6 |...
10003 | gxyz | 4 | 8 | 7 |...
我需要输出不同的文件
文件1:
Code | Name | Day1
10001 | abcd | 5
10002 | degg | 3
10003 | gxyz | 4
文件2:
Code | Name | Day2
10001 | abcd | 1
10002 | degg | 9
10003 | gxyz | 8
文件3:
Code | Name | Day3
10001 | abcd | 9
10002 | degg | 6
10003 | gxyz | 7
依旧......
我写了这样的代码
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$3}' FILE_NAME > file1;
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$4}' FILE_NAME > file2;
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$5}' FILE_NAME > file3;
依旧......
现在我需要在' for'中编写它。或者'而'循环哪个会更快......
我不知道确切的代码,可能是这样的..
for (( i=3; i<=NF; i++)) ; do awk 'BEGIN { FS = "\t" } ; {print $1,$2,$i}' input.tsv > $i.tsv; done
请按照我的解释帮助我获得输出。
答案 0 :(得分:2)
bash + 剪切 解决方案:
input.tsv 测试内容:
Code | Name | Day1 | Day2 | Day3
10001 | abcd | 5 | 1 | 9
10002 | degg | 3 | 9 | 6
10003 | gxyz | 4 | 8 | 7
day_splitter.sh 脚本:
#!/bin/bash
n=$(cat $1 | head -1 | awk -F'|' '{print NF}') # total number of fields
for ((i=3; i<=$n; i++))
do
fn="Day"$(($i-2)) # file name containing `Day` number
$(cut -d'|' -f1,2,$i $1 > $fn".txt")
done
<强> 用法 强>:
bash day_splitter.sh input.tsv
<强> 结果 强>:
$cat Day1.txt
Code | Name | Day1
10001 | abcd | 5
10002 | degg | 3
10003 | gxyz | 4
$cat Day2.txt
Code | Name | Day2
10001 | abcd | 1
10002 | degg | 9
10003 | gxyz | 8
$cat Day3.txt
Code | Name | Day3
10001 | abcd | 9
10002 | degg | 6
10003 | gxyz | 7
答案 1 :(得分:2)
如果你绝对需要在Bash 中使用循环,那么你的循环可以像这样修复:
for ((i = 3; i <= 10; i++)); do awk -v field=$i 'BEGIN { FS = "\t" } { print $1, $2, $field }' input.tsv > file$i.tsv; done
但是使用纯awk解决这个问题会更好,完全没有shell:
awk -v FS='\t' '
NR == 1 {
for (i = 3; i < NF; i++) {
fn = "file" (i - 2) ".txt";
print $1, $2, $i > fn;
print "" >> fn;
}
}
NR > 2 {
for (i = 3; i < NF; i++) {
fn = "file" (i - 2) ".txt";
print $1, $2, $i >> fn;
}
}' inputfile
也就是说,当你在第一张唱片上时, 通过编写标题行和空行来创建输出文件(如问题中指定的那样)。
对于第3个及以后的记录,请附加到文件。
请注意,问题中的代码表明文件中的字段由制表符分隔,但示例文件似乎使用|
填充了可变数量的空格。目前尚不清楚哪一个是你的实际案例。如果它真的以制表符分隔,则上述代码将起作用。如果实际上它是示例输入,则将第一行更改为:
awk -v OFS=' | ' -v FS='[ |]+' '
答案 2 :(得分:0)
纯粹的awk:
$ awk 'BEGIN{FS=OFS="|"}{for(i=3;i<=NF;i++) {f="file" (i-2); print $1,$2,$i >> f; close(f)}}' file
说明:
$ awk '
BEGIN {
FS=OFS="|" } # set delimiters
{
for(i=3;i<=NF;i++) { # loop the consumption fields
f="file" (i-2) # create the filename
print $1,$2,$i >> f # append to target file
close(f) } # close the target file
}' file