В хорошей структуре 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 . Так как два ваших исходных троичных оператора могут возвращать пустые строки, они гарантируют, что логическое И вернет false, что эквивалентно числу ZERO. Следовательно, $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 ...