Итеративно отредактируйте один файл

У меня есть один файл с выражением, который выглядит так:

myName_tx_1 VARCHAR(255) myName_in_1 VARCHAR(255) myName_tx_2 VARCHAR(255) myName_in_2 VARCHAR(255) myName_tx_3 VARCHAR(255) myName_in_3 VARCHAR(255) myAddress_tx_1 VARCHAR(255) myAddress_in_2 VARCHAR(255) etc 

Я хотел бы изменить это на:

 myName_tx_1 VARCHAR(255) myName_in_1 VARCHAR(1) myName_tx_2 VARCHAR(255) myName_in_2 VARCHAR(1) myName_tx_3 VARCHAR(255) myName_in_3 VARCHAR(1) myAddress_tx_1 VARCHAR(255) myAddress_in_2 VARCHAR(1) etc 

В любом случае, дальнейшая квалификация проблемы заключается в том, что я хочу только изменить записи, где имя атрибута заканчивается на «в $», где $ – число (например, myName_in_3 VARCHAR (255)).

Как бы то ни было, атрибуты «_in» (индикаторы) попадают парами, поэтому n ~ 2 (или FNR% 2 == 0) довольно умный, но я действительно задаюсь вопросом, лучше ли идентифицировать '_in $ VARCHAR ( 255) 'как шаблон изменения.

Как мне это сделать, используя легко понятный код? Файл невелик, поэтому производительность не является главной проблемой … просто пытается избежать большого редактирования вручную.

С помощью GNU sed вы можете указать адреса линий в формате first~step , чтобы изменить каждую другую строку, начиная со второй, вы можете использовать адрес 2~2 например

 $ sed '2~2 s/(255)/(1)/' file myName_tx_1 VARCHAR(255) myName_in_1 VARCHAR(1) myName_tx_2 VARCHAR(255) myName_in_2 VARCHAR(1) myName_tx_3 VARCHAR(255) myName_in_3 VARCHAR(1) myAddress_tx_1 VARCHAR(255) myAddress_in_2 VARCHAR(1) 

С awk :

 $ awk 'FNR%2==0{sub(255,1)}1' file myName_tx_1 VARCHAR(255) myName_in_1 VARCHAR(1) myName_tx_2 VARCHAR(255) myName_in_2 VARCHAR(1) myName_tx_3 VARCHAR(255) myName_in_3 VARCHAR(1) myAddress_tx_1 VARCHAR(255) myAddress_in_2 VARCHAR(1) 

объяснение

  • FNR%2==0 только строкам.
  • Если строка четная, мы заменим 255 на 1 , sub(255,1) .
  • 1 – истинное условие, сделайте awk print $0 .

Та же логика может использоваться с другими инструментами, такими как perl :

 perl -pe 's/255/1/ unless $. % 2' file 

С помощью sed вы можете:

 sed -e 'n;s/255/1/' file 

Обновить

С вашим требованием к обновлению мы можем немного изменить решение.

С awk :

 awk '/_in_[0-9]/{sub(255,1)}1' file 

С sed :

 sed -e '/_in_[0-9]/{s/255/1/}' file 

С perl :

 perl -pe 's/255/1/ if /_in_[0-9]/' file 

Там в

 sed '/_in_/ s/255/1/' 

что означает: для строк, соответствующих /_in_/ , поиск 255 и замена на 1 .

 cat oldfile.txt |awk '/_in_[0-9]/{sub(255,1)}1' > newfile.txt