![如何使用 NF 和 for 循环优化脚本](https://linux22.com/image/117343/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20NF%20%E5%92%8C%20for%20%E5%BE%AA%E7%8E%AF%E4%BC%98%E5%8C%96%E8%84%9A%E6%9C%AC.png)
我有几个文件,每个文件都有不同的列数。我想将它们转换为将它们插入数据库
例如文件 test01:
0001 000000000000001 john smith 45 500
0002 000000000000002 peter jackson 20 80
0003 000000000000002 robert brown 35 100
0004 000000000000007 sarah white 40 300
我想要的输出是:
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');
为了实现这一点,我使用以下脚本:
cat test01 |awk -F'\t' '{print "('\''"$1"'\'','\''"$2"'\'','\''"$3"'\'','\''"$4"'\'','\''"$5"'\''),"}' |sed '$ s/.$/;/'
它工作正常,问题是当我找到另一个具有不同列数的文件时,所以我必须手动修改脚本。
我知道我可以使用 AWK 的变量 NF 获取列数,但是如何将此变量与脚本中的 for 循环结合起来?
当我尝试时
cat test01 | awk '{for (i = 1; i <= NF; i++){print $i"'\'','\''"}}'
我得到这个结果:
0001','
000000000000001','
john','
smith','
45','
500','
0002','
000000000000002','
peter','
jackson','
20','
80','
0003','
000000000000002','
robert','
brown','
35','
100','
0004','
000000000000007','
sarah','
white','
40','
300','
答案1
如果您的输入文件是制表符分隔的,您可以尝试以下操作:
awk -F"\t" -v q="'" -v OFS="','" '$1=$1 {print "(" q $0 q ");"}' filename
或者在 print 函数中嵌入引号:
awk -F"\t" -v OFS="','" '$1=$1 {print "(" "\x27" $0 "\x27" ");"}' filename
答案2
使用 GNU sed
:
$ sed -e "s/^/('/" -e "s/\t/','/g" -e "s/$/'),/" -e '$s/.$/;/' file
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');
该sed
脚本分为四个部分:
s/^/('/
将行首替换为('
.s/\t/','/g
将选项卡替换为','
.这是需要 GNU 的部分sed
。对于其他sed
实现,请插入文字制表符来代替\t
。s/$/'),/
将行尾替换为'),
.$s/.$/;/
(仅)用 替换最后一行末尾的逗号;
。
答案3
要通过初始脚本达到与您想要的相同的行为,您可以使用 awk 的“printf”方法。它可以摆脱“print”放置的换行符。我猜,你的脚本应该这样重写:
cat test01 | awk '{for (i = 1; i <= NF; i++){printf $i"'\'','\''"}; printf "\n";}'
答案4
这是我的尝试......
我的语句由3部分组成:cat、awk、sed
awk 和 sed 语句肯定可以改进,但我仍在学习它们。我将 test01 改为 test2.txt
cat test2.txt | awk -F "\\t| " 'BEGIN {ORS=""}{print "("}{ORS=","}{for (i = 1; i <= NF; i++){print "'\''"$i"'\''"}}{print ")\n"}{ORS=""}' | sed 's/,)/),/' | sed 's/^,//' | sed '$ s/),/);/'