之間的數據文件空間 - data.txt中:awk中考慮雙引號的字符串作爲一個令牌,而忽略
ABC "I am ABC" 35 DESC
DEF "I am not ABC" 42 DESC
cat data.txt | awk '{print $2}'
將導致了「我」不是字符串被引用
如何使AWK,使其忽略引號內的空間,並認爲它是一個單一的令牌?
之間的數據文件空間 - data.txt中:awk中考慮雙引號的字符串作爲一個令牌,而忽略
ABC "I am ABC" 35 DESC
DEF "I am not ABC" 42 DESC
cat data.txt | awk '{print $2}'
將導致了「我」不是字符串被引用
如何使AWK,使其忽略引號內的空間,並認爲它是一個單一的令牌?
是的,這可以很好地在AWK完成。沒有任何嚴重的黑客攻擊都很容易。
(這個例子工作在兩個The One True Awk和GAWK)。
{
split($0, a, "\"")
$2 = a[2]
$3 = $(NF - 1)
$4 = $NF
print "and the fields are ", $1, "+", $2, "+", $3, "+", $4
}
試試這個:
$ cat data.txt | awk -F\" '{print $2}'
I am ABC
I am not ABC
我要指出,這是不是特別的通用 - 它只是將字段分隔符更改爲'「並選擇第二個字段 –
但是,如果我想在使用前後的信息...它不會工作=( –
@羅伊陳 - 真,Awk是不是真的是正確的解析引用字符串的工具。回到第三篇文章[在這個可怕的格式化Google緩存鏈接](http://webcache.googleusercontent.com/search?q=cache:HA9Ix2yPEasJ:forums11.itrc.hp.com/service/forums/questionanswer.do% 3FthreadId%3D1028610 + awk + quotes + field&cd = 1&hl = en&ct = clnk&gl = us&client = safari&source = www.google.com),您可以看到一個時間更長但可能有所幫助的示例。 –
好吧,如果你真的想所有三個字段,你可以讓他們,但它需要大量的管道:
$ cat data.txt | awk -F\" '{print $1 "," $2 "," $3}' | awk -F' ,' '{print $1 "," $2}' | awk -F', ' '{print $1 "," $2}' | awk -F, '{print $1 "," $2 "," $3}'
ABC,I am ABC,35
DEF,I am not ABC,42
到最後管你有三個字段做任何你想用喜歡。
其實,有4個字段。 – DigitalRoss
哎呀 - 我錯過了原來的提交。 –
我揉成一團在一起重新分割$ 0改成叫B.雙引號之間的空間不作爲字段分隔陣列功能。可以與任意數量的字段一起使用,這些字段是引用引用和未引用引用的字段。這裏有:
#!/usr/bin/gawk -f
# Resplit $0 into array B. Spaces between double quotes are not separators.
# Single quotes not handled. No escaping of double quotes.
function resplit( a, l, i, j, b, k, BNF) # all are local variables
{
l=split($0, a, "\"")
BNF=0
delete B
for (i=1;i<=l;++i)
{
if (i % 2)
{
k=split(a[i], b)
for (j=1;j<=k;++j)
B[++BNF] = b[j]
}
else
{
B[++BNF] = "\""a[i]"\""
}
}
}
{
resplit()
for (i=1;i<=length(B);++i)
print i ": " B[i]
}
希望它有幫助。
對於這個問題的答案頂部僅適用於具有單引號場線。當我發現這個問題時,我需要一些可以用於任意數量的引用字段的東西。
最終我來到an answer by Wintermute in another thread,他提供了一個很好的通用解決了這個問題。我剛剛修改它以刪除引號。請注意,在運行以下程序時,需要使用-F\"
調用awk。
BEGIN { OFS = "" } {
for (i = 1; i <= NF; i += 2) {
gsub(/[ \t]+/, ",", $i)
}
print
}
這個工程通過觀察數組中的所有其他元素將是引號內,當你在「字符數限制分離,所以它取代了空格分割的那些不與逗號報價。
,您可以很容易連鎖AWK做你需要的任何處理(只是再次使用字段分隔開關,-F,
)的另一個實例
注意的是,如果第一場是引用這可能會打破 - 我沒有然後測試它,如果確實如此,應該很容易通過添加if語句來在2 rath開始如果該行的第一個字符是「」,則該值大於1。
這是什麼像什麼,我終於得到了工作就是爲我的項目更通用。 注意它不使用awk。
someText="ABC \"I am ABC\" 35 DESC '1 23' testing 456"
putItemsInLines() {
local items=""
local firstItem="true"
while test $# -gt 0; do
if [ "$firstItem" == "true" ]; then
items="$1"
firstItem="false"
else
items="$items
$1"
fi
shift
done
echo "$items"
}
count=0
while read -r valueLine; do
echo "$count: $valueLine"
count=$(($count + 1))
done <<< "$(eval putItemsInLines $someText)"
,其輸出:
0: ABC
1: I am ABC
2: 35
3: DESC
4: 1 23
5: testing
6: 456
要格式化單行:'cat data.txt | awk'split($ 0,a,「\」「){$ 2 = a [2]} {$ 3 = $(NF-1)} {$ 4 = $ NF} {print」,字段爲「,$ 1,」+ 「,$ 2,」+「,$ 3,」+「,$ 4}'' –
只有在第二個位置有單引號字段並且共有4個字段時纔有效。將接受在任何位置的任何引用字段將是理想的。 –