如何在 shell 脚本中递归使用粘贴命令
How to use paste command recursively in a shell script
我的脚本中有一个粘贴命令。但它没有给出我想要的输出。我的数据文件是
file.txt
1
3
5
4
我的 shell 脚本是
f1=file.txt
for j in 1..12
do
awk '{printf ("%.1f\n", +'$j');}' $f1 > $j_$f1
paste $j_$f1 > ofile.txt # ofile.txt is a new empty file
done
此脚本的输出为
ofile.txt
2
4
6
5
3
5
7
6
.
.
我想要的输出为
ofile.txt
2 3 4 5 6 ... 13
4 5 6 7 8 ... 15
6 7 8 9 10 .. 17
5 6 7 8 9 ... 16
下面的脚本我也想做
bonus_company1=10
bonus_company2=25
bonus_company3=50
declare var=("company1" "company2" "company3")
for k in var{[@]}
do for j in jan..dec
do if [ $j == "jan" ] || [ $j == "may" ] || [ $j == "sep" ]; then
awk '{printf ("%.1f\n", + '$bonus_$k');}' $f1 > $k_$j_$f1
elif [ $j -ne "jan" ] && [ $j -ne "may" ] && [ $j -ne "sep" ]; then
awk '{printf ("%.1f\n", +5);}' $f1 > $k_$j_$f1
fi
paste $k_$j_$f1 > $k.txt # $k.txt is a new empty file
done
done
所以我会得到三个公司的 3 个不同的文件。例如
company1.txt
11 6 6 6 11 .....
13 8 8 8 11 .....
15 10 10 10 15 .....
14 9 9 9 14 .....
我建议在 awk 中完成所有操作,而不是使用 shell 循环:
awk '{for (i=1; i<=12; ++i) printf "%d%s", +i, (i<12?FS:RS)}' "$f1" > output
此循环针对文件的每一行运行并输出所有列,从而无需使用其他工具,例如 paste
。三元运算符用于在每列之间输出一个space(FS
),并在行尾输出一个换行符(RS
)。
对于你问题的第二部分,你仍然可以在 awk 中完成大部分工作。
declare -A companies
companies=( [company1]=10 [company2]=25 [company3]=50 )
for c in "${companies[@]}"; do
awk -v bonus="${companies[c]}" '{for (i=1; i<=12; ++i)
printf "%d%s", $i+(i==1||i==5||i==9?bonus:5), (i<12?FS:RS)}' "$f1" > "$c.txt"
done
我创建了一个包含每个公司名称及其奖金的关联数组。循环遍历数组中的每个公司,将奖金作为变量传递给 awk(请注意,我这样做是使用 -v
而不是使用字符串连接)。循环从 1 到 12,添加第 1、5 和 9 个月的奖金,否则为第 5 个月。公司名称(shell 数组的键)用于输出文件。
我不明白,你为什么要走这么复杂的路。你可以用更简单的方式来做:
第二个:
for k in var{[@]}
do awk '{printf("%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", +"$bonus_$k", +5, +5, +5, +"$bonus_$k", +5, +5, +5, +"$bonus_$k", +5, +5, +5);}' file.txt > $k_file.txt
done
我的脚本中有一个粘贴命令。但它没有给出我想要的输出。我的数据文件是
file.txt
1
3
5
4
我的 shell 脚本是
f1=file.txt
for j in 1..12
do
awk '{printf ("%.1f\n", +'$j');}' $f1 > $j_$f1
paste $j_$f1 > ofile.txt # ofile.txt is a new empty file
done
此脚本的输出为
ofile.txt
2
4
6
5
3
5
7
6
.
.
我想要的输出为
ofile.txt
2 3 4 5 6 ... 13
4 5 6 7 8 ... 15
6 7 8 9 10 .. 17
5 6 7 8 9 ... 16
下面的脚本我也想做
bonus_company1=10
bonus_company2=25
bonus_company3=50
declare var=("company1" "company2" "company3")
for k in var{[@]}
do for j in jan..dec
do if [ $j == "jan" ] || [ $j == "may" ] || [ $j == "sep" ]; then
awk '{printf ("%.1f\n", + '$bonus_$k');}' $f1 > $k_$j_$f1
elif [ $j -ne "jan" ] && [ $j -ne "may" ] && [ $j -ne "sep" ]; then
awk '{printf ("%.1f\n", +5);}' $f1 > $k_$j_$f1
fi
paste $k_$j_$f1 > $k.txt # $k.txt is a new empty file
done
done
所以我会得到三个公司的 3 个不同的文件。例如
company1.txt
11 6 6 6 11 .....
13 8 8 8 11 .....
15 10 10 10 15 .....
14 9 9 9 14 .....
我建议在 awk 中完成所有操作,而不是使用 shell 循环:
awk '{for (i=1; i<=12; ++i) printf "%d%s", +i, (i<12?FS:RS)}' "$f1" > output
此循环针对文件的每一行运行并输出所有列,从而无需使用其他工具,例如 paste
。三元运算符用于在每列之间输出一个space(FS
),并在行尾输出一个换行符(RS
)。
对于你问题的第二部分,你仍然可以在 awk 中完成大部分工作。
declare -A companies
companies=( [company1]=10 [company2]=25 [company3]=50 )
for c in "${companies[@]}"; do
awk -v bonus="${companies[c]}" '{for (i=1; i<=12; ++i)
printf "%d%s", $i+(i==1||i==5||i==9?bonus:5), (i<12?FS:RS)}' "$f1" > "$c.txt"
done
我创建了一个包含每个公司名称及其奖金的关联数组。循环遍历数组中的每个公司,将奖金作为变量传递给 awk(请注意,我这样做是使用 -v
而不是使用字符串连接)。循环从 1 到 12,添加第 1、5 和 9 个月的奖金,否则为第 5 个月。公司名称(shell 数组的键)用于输出文件。
我不明白,你为什么要走这么复杂的路。你可以用更简单的方式来做:
第二个:
for k in var{[@]}
do awk '{printf("%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", +"$bonus_$k", +5, +5, +5, +"$bonus_$k", +5, +5, +5, +"$bonus_$k", +5, +5, +5);}' file.txt > $k_file.txt
done