[英]AWK in single line pass multiple commands
我想將以下多個awk命令組合到一個awk程序中:
awk -F 'FS' '{ $1 = ($1 == "}" ? "" : $1) } 1' sorce > destfil
awk -F 'FS' '{ $3 = ($3 == "]" ? "" : $3) } 1' sorce > destfil
awk -F 'FS' '{ $5 = ($5 == "}" ? "}," : $5) } 1' sorce > destfil
我試圖使用&&
完成此操作,但結果卻不是我期望的。
awk -F 'FS' '{ $1 = ($1 == "}" ? "" : $1) && $3 = ($3 == "]" ? "" : $3) && $5 = ($5 == "}" ? "}," : $5) } 1' sorce > destfil
輸出中似乎包含各種零。
題:
謝謝!
@ RavinderSingh13,當我嘗試您的代碼時,請按照以下示例輸入文件和輸出文件
[user@restt]$ tail source
{
}
]
}
{
" e t
{
}
]
}
[user@test]$ awk -F 'FS' '{$1=($1=="}"?"":$1); $3=($3=="]" ? "" : $3) ; $5=($5=="}" ? "}," :$5);} 1' source > target
[user@test]$ tail target
{
}
]
}
{
" e t
{
}
]
}
我認為問題與字段分隔符-F'FS'有關,或者我不確定。
@kvantour,在下面,我給了我的示例輸入文件,並命令了我正在運行的東西,正在獲得的輸出以及我需要的東西。
源文件內容:
{
"metadata": [
{
sample content line 1
sample content line n
}
]
}
{
"metadata": [
{
sample content line 1
sample content line n
}
]
}
{
"metadata": [
{
sample content line 1
sample content line n
}
]
}
{
"metadata": [
{
sample content line 1
sample content line n
}
]
}
我正在運行的命令
$ awk '($1=="}"){$1="First Column"}
($3=="]"){$3="third Column"}
($5=="}"){$5="Fifth Column"}
{$1=$1}1' sample.json > out
我得到的輸出:
[root@centos-src ~]# cat out
{
"metadata": [
{
sample content line 1
sample content line n
First Column
]
First Column
{
"metadata": [
{
sample content line 1
sample content line n
First Column
]
First Column
{
"metadata": [
{
sample content line 1
sample content line n
First Column
]
First Column
{
"metadata": [
{
sample content line 1
sample content line n
First Column
]
First Column
但我期望輸出是:
{
"metadata": [
{
sample content line 1
sample content line n
Fifth Column
third Column
First Column
{
"metadata": [
{
sample content line 1
sample content line n
Fifth Column
third Column
First Column
{
"metadata": [
{
sample content line 1
sample content line n
Fifth Column
third Column
First Column
{
"metadata": [
{
sample content line 1
sample content line n
Fifth Column
third Column
First Column
在一個不錯的awk結構中,可以這樣寫:
awk -F 'FS' '($1=="}"){$1=""}
($3=="]"){$3=""}
($5=="}"){$5="},"}
{$1=$1}1' <file>
我將$1=$1
添加到列表的原因是,在上述條件均不滿足的情況下,為了正確的OFS
重新處理$0
。 如果不這樣做,您將使用FS
作為行分隔符打印行,而使用OFS
打印。
那么,為什么要得到一堆零呢?
讓我們看一下您的單線:
$1 = ($1 == "}" ? "" : $1) && $3 = ($3 == "]" ? "" : $3) && $5 = ($5 == "}" ? "}," : $5)
並假設括號之間的三元運算符返回一個變量,從而對其進行簡化。 因此我們可以將其重寫為:
$1 = var1 && $3 = var3 && $5 = var5
考慮到:
expr1 && expr2
的優先級高於value = expr
。 lvalue = expr
返回lvalue = expr
的值 我們可以看到awk將其解釋為
$1 = var1 && ($3 = (var3 && ($5 = var5) ) )
因此結果將是:
$5 = var5
$3 = var3 && $5 equalling var3 && var5
$1 = var1 && $3 equalling var1 && var5
在以下示例中可見:
$ echo "a b c d e f" | awk '{ $1="p" && $3 = "q" && $5 = "r"}1'
1 b 1 d rf
最后,在awk
,空字符串和數字零具有邏輯值false和其他任何值true 。 因此,由於您的兩個原始三元運算符可以返回空字符串,因此它們將確保邏輯AND將返回false,這等效於數字ZERO。 因此, $1
和$3
將均具有零匹配,如果原來的$3
等號]
您嘗試實現的目標並不那么容易。 首先,您似乎假設列號暗含了該行中的字符號。 不幸的是事實並非如此。 在默認模式下,Awk假定字段$n
是該行中的第n
個單詞,其中單詞是不包含任何空格的字符序列。 所以在下面的文字中,
}
]
}
$1
實際上引用了所有字符。
假設您的JSON文件是完全縮進的,則可以使用以下內容:
awk '/^} *$/{$0="First Column"}
/^ ] *$/{$0=" Thrid Column"}
/^ } *$/{$0=" Fifth Column"}
{print $0}' <file>
但是,如果您的JSON文件沒有統一縮進,則情況會變得很混亂。 最簡單的方法是首先使用jq
將文件解析為
jq . <json-file> | awk ...
這是您要嘗試執行的操作(鑒於您的source
輸入文件)?
$ awk '
BEGIN{ FS="[ ]"; map[1,"}"]=map[3,"]"]=map[5,"}"]="" }
{ for (i=1;i<=NF;i++) $i=((i,$i) in map ? map[i,$i] : $i); print }
' file
{
{
" e t
{
由於您尚未顯示示例Input_file,因此無法對其進行測試,請嘗試以下操作。
awk -F 'FS' '{$1=($1=="}"?"":$1);$3=($3=="]"?"":$3);$5=($5=="}"?"":$5);} 1' sorce > destfil
用法;
分開陳述:
awk ... '{ $1 = ($1 == "}" ? "" : $1); $3 = ($3 == "]" ? "" : $3); $5 = ($5 == "}" ? "}," : $5); } 1' ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.