从命令行递归多行查找/替换

时间:2018-01-16 19:49:28

标签: regex shell perl

我正在尝试查找和替换js文件中的import语句。我需要考虑一些不同的变体:

// default-import.js
import foo from 'bar-shared';

// named-import.js
import {Foo} from 'bar-shared/foo';

// type-import.js
import type {FooType} from 'bar-shared/foo';

// multiline-import.js
import {
  Foo,
  reduceFoo,
} from 'bar-shared/foo';

// multiline-with-type-import.js
import {
  Foo,
  reduceFoo,
  type FooType,
} from 'bar-shared/foo';

// multiple-import.js
import foo from 'bar-shared';
import {Foo} from 'bar-shared/foo';
import {
  Baz
  reduceBaz
} from 'bar-shared/baz';

我的最终目标是将bar-shared替换为@bar/core。但限制是: - 我不知道具体的进口是什么 - import语句可以是多行 - 单个文件中可以有bar-shared个多个import语句

我已经合理地接近以下内容:

find . -type f -name "*.js" -exec \
  perl -0777 -p -i -e "s/^import ([\s\S]*?) from 'bar-shared(.*)'/import \1 from '\@bar\/core\2'/gms" {} +

该脚本似乎没有找到所有实例。特别是最终的示例类型,在文件中有多个import语句,似乎是真正的问题。

1 个答案:

答案 0 :(得分:2)

您似乎始终需要从import到第一个from 'bar-shared'进行匹配。然后

perl -i -0777 -wpe's{import.*?from\s+\x27\Kbar\-shared}{\@bar/core}gs'

\x27是单引号的hexadecimal escape(27)。 /s修饰符也会使.与换行符匹配,这就是以这种方式处理此多行字符串所需的全部内容。 \K会丢弃之前的所有匹配项,因此无需捕获和替换它们。

测试了您的示例,但我不确定JS中的import块中可能出现的内容。