Как я могу изменить «long» на «int», не меняя «long long», используя perl / awk / etc - PullRequest
3 голосов
/ 18 августа 2011

Я хочу изменить все long с на int с (при подготовке к 64-битному коду).У меня есть строка Perl:

s/(\s*long\s+)(?!long)/ int /g

, которая подходит близко.Он меняет long на int и long long на long int.

Любой метод редактирования хорош, если он может быть написан по сценарию или работать с несколькими файлами.

*Sample:  input              desired output*
   long abd;                   int abd;
int longname;               int longname;
int reallylongname;         int reallylongname;
float reallylong longname;  float reallylong longname;
double namelong             double namelong
long abc long               int abc int
long long abc               long long abc
long    long hhhh           long    long hhhh
long long hhhh              long long hhhh
long abd( long kjhh         int abd( int kjhh

Ответы [ 4 ]

4 голосов
/ 18 августа 2011

Следующее было бы идеально, если бы поддерживались видоискатели переменной ширины:

s/
   (?<! \b long \s+)
   \b long \b
   (?! \s+ long \b)
/int/xg

Это оставляет вас в беспорядке:

s/
   \b ( (?: long \s+ )* ) long \b
/
   length($1) ? $1."long" : "int"
/xeg

Обновление : Это также работает:

s/
   (?<! \b long )
   (?<! \s ) \s* \K
   \b long \b
   (?! \s+ long \b)
/int/xg

Обновление : протестировано с использованием:

use strict;
use warnings;

use Test::More;

sub fix {
   my ($s) = @_;
   $s =~ s/
      \b ( (?: long \s+ )* ) long \b
   /
      length($1) ? $1."long" : "int"
   /xeg;
   return $s;
}

my @tests = (
   [ '   long abd;',                '   int abd;'                ],
   [ 'int longname;',               'int longname;'              ],
   [ 'int reallylongname;',         'int reallylongname;'        ],
   [ 'float reallylong longname;',  'float reallylong longname;' ],
   [ 'double namelong',             'double namelong'            ],
   [ 'long abc long',               'int abc int'                ],
   [ 'long long abc',               'long long abc'              ],
   [ 'long    long hhhh',           'long    long hhhh'          ],
   [ 'long long hhhh',              'long long hhhh'             ],
   [ 'long abd( long kjhh',         'int abd( int kjhh'          ],
);

plan tests => 0+@tests;

for (@tests) {
   my ($i,$e) = @$_;
   my $g = fix($i);
   is($g, $e, $i);
}

1;
1 голос
/ 18 августа 2011

Если вы готовы сделать четыре прохода, конвертируйте long int в long$int, конвертируйте long в int, затем int int в long long и long$int обратно в long int.

1 голос
/ 18 августа 2011
sed -e 's/\blong  *int\b/int/g' -e 's/\blong\b/int/g' -e 's/\bint\(  *\)int\b/long\1long/g'

Просто заменить те обратно, которые теперь не так?

правки: добавлено сохранение пробелов, добавлено исправление Kerrek SB

0 голосов
/ 18 августа 2011
foreach my $line (@lines_in_the_file) {
    $line =~ s/\blong long\b/SOMETHINGFUNKY/g;
}

foreach my $line (@lines_in_the_file) {
    $line =~ s/\blong\b/int/g;
}

foreach my $line (@lines_in_the_file) {
    $line =~ s/SOMETHINGFUNKY/long long/g;
}
...