簡體   English   中英

使用awk用單引號將單個字段引起來

[英]Wrap a single field with single quotes using awk

有許多使用awk來包裝帶雙引號的字段的示例。 我一直在嘗試用單引號括住一個字段,以便在PostgreSQL中加載csv文件的數據。

以下是我的一些嘗試:

#!/usr/bin/awk -f
BEGIN { FS=OFS=","}

{
  for (i = 1; i <= NF; ++i)
    if($i == 9)
    {
        $i = "\'' $i \''"
    }

  print $0 >> "output.csv"
}

要么

awk 'BEGIN { OFS=FS="," } { $9= ""'" $9 ""'"} 1' container.csv > output.csv

也...

awk -v q="'" 'BEGIN { FS="," } { sub($9, ""\'"&"\'"" );print}' container.csv > output.csv
$ awk 'BEGIN { FS = OFS = "," } { $9= "'"'"'" $9 "'"'"'"; print }' \
>    <<<one,two,three,four,five,six,seven,eight,nine,ten
one,two,three,four,five,six,seven,eight,'nine',ten

棘手的事情是通過bash將引號輸入到awk中-如果您在單引號命令行參數中使用單引號,則將其視為以'BEGIN開頭的引號上下文結束,而不是原義發送到awk

因此, "'"'"'"做必要的欺騙:

  • 第一個字符"是文字,傳遞給awk
  • 第二個字符'是語法,用於告訴Shell結束從命令行開頭開始的引號
  • 第三個字符"是句法,用於開始新的(雙引號)引用上下文。
  • 第四個字符'是該上下文中的文字。
  • 第五個字符"結束從字符三開始的雙引號上下文
  • 第六個字符'是語法,恢復以第二個字符結尾的單引號上下文
  • 第七個字符"是原義,傳遞給awk。

因此,上面傳遞給awk用作腳本實際上是:

BEGIN { FS = OFS = "," } { $9= "'" $9 "'"; print }

...如果願意,您可以直接將其放在文件中; 如果該awk腳本具有#!/usr/bin/awk -f shebang,則在直接作為命令執行時應該可以工作。


順便說一句,如果您的shell是bash,那么會有一個替代的引用上下文,這將使這不太可怕:

$ awk $'BEGIN { FS = OFS = "," } { $9= "\'" $9 "\'"; print }'

$'' ,反斜杠轉義符--- \\t是制表符, \\f是字段分隔符, \\r是換行符,並且-與我們的觀點有關- \\'是單引號。

這在腳本中容易得多 ,因為您不必擔心其中的引號:

BEGIN { FS = OFS = "," }

{ 
    $9 = "'" $9 "'"
    print
}

我不確定您的循環應該做什么!

使用Charles提供的輸入進行測試:

$ cat file
one,two,three,four,five,six,seven,eight,nine,ten
$ awk -f script.awk file
one,two,three,four,five,six,seven,eight,'nine',ten

只需在需要單引號的地方使用八進制轉義序列\\047

awk 'BEGIN{FS=OFS=","} { $9= "\047" $9 "\047"; print }'

這避免了報價中的任何復雜性,也避免了其他方法帶來的任何意外。

使用sed解決方案

$ s='one,two,three,four,five,six,seven,eight,nine,ten'

$ # s///n means nth matching occurrence
$ echo "$s" | sed "s/[^,]*/'&'/9"
one,two,three,four,five,six,seven,eight,'nine',ten
$ # * used as quantifier so that it will work on empty fields too
$ echo 'a,c,,d' | sed "s/[^,]*/'&'/3"
a,c,'',d  

$ # or if hex escape sequences are allowed
$ # this is preferred as it avoids shell interpretation within double quotes
$ echo "$s" | sed 's/[^,]*/\x27&\x27/9'
one,two,three,four,five,six,seven,eight,'nine',ten

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM