单行AWK传递多个命令

时间:2018-09-10 11:39:29

标签: bash awk

我想将以下多个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

输出中似乎有各种零。

问题:

  • 如何合并这些行?
  • ZEROS的起源是什么?

谢谢!


@ 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

4 个答案:

答案 0 :(得分:2)

在一个不错的awk结构中,可以这样写:

awk -F 'FS' '($1=="}"){$1=""}
             ($3=="]"){$3=""}
             ($5=="}"){$5="},"}
             {$1=$1}1' <file>

我将$1=$1添加到列表中的原因是,在上述条件均不满足的情况下,为了正确的$0重新处理OFS。如果不这样做,则将行打印为FS作为行分隔符,而其他行则打印为OFS

那你为什么要得到一堆零?

让我们看看你的单线纸:

$1 = ($1 == "}" ? "" : $1) &&  $3 = ($3 == "]" ? "" : $3) && $5 = ($5 == "}" ? "}," : $5)

并通过假设括号之间的三元运算符返回变量来简化它。因此我们可以将其重写为:

$1 = var1 && $3 = var3 && $5 = var5

考虑到以下因素:

  • expr1 && expr2的优先级高于value = expr
  • lvalue = expr返回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,这等于数字0。因此,如果原始$1等于$3

$3]都将与零匹配。

更新(收到[mcve]后)

您试图实现的目标并不那么容易。首先,您似乎假设列号暗含了该行中的字符号。不幸的是事实并非如此。在默认模式下,Awk假定字段$n是该行中的第n个单词,其中单词是不包含任何空格的字符序列。因此,在以下文本中,

    }
  ]
}

$1实际上引用了所有字符。

在假设您的JSON文件完全缩进的情况下,可以使用以下内容:

awk '/^} *$/{$0="First Column"}
     /^  ] *$/{$0="  Thrid Column"}
     /^    } *$/{$0="    Fifth Column"}
     {print $0}' <file>

但是,如果您的JSON文件没有统一缩进,则情况会变得很混乱。最简单的方法是首先将jq解析为

jq . <json-file> | awk ...

答案 1 :(得分:1)

这是您要尝试做的吗(给定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
    {

答案 2 :(得分:0)

由于您没有显示示例Input_file,因此无法对其进行测试,请您尝试以下操作。

awk -F 'FS' '{$1=($1=="}"?"":$1);$3=($3=="]"?"":$3);$5=($5=="}"?"":$5);} 1' sorce > destfil

答案 3 :(得分:0)

使用;分隔语句:

awk ... '{ $1 = ($1 == "}" ? "" : $1); $3 = ($3 == "]" ? "" : $3); $5 = ($5 == "}" ? "}," : $5); } 1' ...