Замените строку, которая является двумя строками, предшествующими совпадающему шаблону

#bash #shell #sed

Вопрос:

У меня есть большой config.js файл и я хотел бы заменить default:false, на default:true, тот, который находится сверху field:'$scope.keepEffort' . Я пробовал несколько sed командных решений, но, похоже, ничего не работает.

 {  default:false,  enabled:true,  field:'criticalPath',  filter:false,  filterValue:'',  id:'show-critical-path',  operator:'colorize'  },{  default:false,  enabled:true,  field:'$scope.keepEffort',  filter:false,  filterValue:'',  id:'effort-constant',  operator:'var'  },{  default:false,  enabled:true,  field:'$scope.automaticProgress',  filter:false,  filterValue:'',  id:'automatic-progress',  operator:'var'  },{  default:false,  enabled:true,  field:'groupView',  filter:false,  filterValue:'',  id:'gantt-group-view',  operator:'var'  },{  

Комментарии:

1. Вы должны использовать jq вместо sed .

2. Хорошо, я искал jq и обнаружил, что он предназначен для файла JSON, но мой файл конфигурации не является JSON, хотя он выглядит так из приведенного мной примера кода, но на самом деле это функция JavaScript

Ответ №1:

Для этого и есть работа awk . Ниже не предпринимается попытка сопоставить одинарные кавычки, поскольку для этого требуется некоторое цитирование оболочки, которое запутывает решение. Кроме того, выводится трейлинг { . Это достаточно легко удалить, и код для этого опущен для ясности:

 awk '/field:.$scope.keepEffort/{gsub("default:false","default:true")}1' RS={ ORS={ input-file  

Идея состоит в том, чтобы просто разделить записи, { а затем выполнить подстановку (через gsub ) только для записей, которые соответствуют нужной строке.

Комментарии:

1. Большое вам спасибо, ваше решение работает, но я новичок в командах awk и sed, так как я должен удалить последний дополнительный файл { in, который был добавлен в той же команде

2. Этот финал { добавляется в качестве последней строки, поэтому, вероятно, проще всего просто передать это в sed . например awk ... | sed '$d' . sed Команда удалит последнюю строку.

Ответ №2:

Это может сработать для вас (GNU sed):

 sed ':a;/{/{n;:b;N;/}/!bb;/$scope.keepEffort/s/(default:)false,/1true,/;ba}' file  

Соберите строки между { и } и, если эти строки содержат $scope.keepEffort , замените default:false на default:true .

N. B. Добавление n после сопоставления { , которое позволяет сопоставлять } . Кроме того, возврат к :a после сбора коллекции, чтобы иметь возможность сопоставить другую { .