Awk

如何使用 NF 和 for 循環優化腳本

  • October 7, 2021

我有幾個文件,每個文件都有不同的列數。我想將它們轉換為將它們插入數據庫

例如文件 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','

使用 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腳本分為四個部分:

  1. s/^/('/將行首替換為('.
  2. s/\t/','/g將製表符替換為','. 這是需要 GNU 的位sed。對於其他sed實現,插入一個文字製表符代替\t.
  3. s/$/'),/用 替換行尾'),
  4. $s/.$/;/將最後一行末尾的逗號(僅)替換為;.

如果您的輸入文件是製表符分隔的,您可以嘗試以下操作:

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

引用自:https://unix.stackexchange.com/questions/390101