如何扫描所有文件或某些文本并将其复制到另一个文件?

时间:2019-01-31 09:06:33

标签: node.js bash

我有一个包含许多目录和子目录的大型应用程序。有些文件中有一行带有.styl文件导入的行。例如:

import './view/auth.styl';

我想编写一个sh脚本,该脚本将扫描所有文件,查找此类导入并将它们复制到另一个文件中(让我们说“ global.styl”)。老实说,我不知道如何编写这样的bash脚本。

2 个答案:

答案 0 :(得分:1)

您可以为此使用find:

find /path/to/toplevel/dir -type f -exec grep "import .*styl';" {} \; >> global.styl

说明:查找从给定目录贯穿所有子目录。 型f 仅获取所有文件(而不是目录),并执行grep(在这些文件中查找文本)。 {} \; 只是find查找到的所有文件的占位符。 >> 只是将输出重定向到文件global.styl。

或者如果所有文件都具有扩展名。无论可以使用什么

find /path/to/toplevel/dir -name "*.whatever" -exec grep "import .*styl';" {} \; >> global.styl

因此,您无需使用所有文件,而只需使用具有给定文件名架构的文件

如果您确定导入是行中唯一且唯一且前后没有空格的文本,则可以使用grep“ ^ import。* styl'; $”来检查之前是否没有任何内容(< strong> ^ ),然后在此行中的( $ )之后。 (有关此内容的更多详细信息,请参见regular expressions

答案 1 :(得分:1)

命令

单个grep命令就足够了:

grep -hr 'import .*\.styl' > global.styl

grep搜索文件中的行。仅打印与给定正则表达式匹配的行。我们使用正则表达式import .*\.styl来选择所有包含import的行,然后是某些内容,然后是.styl

使用-r,我们递归搜索当前工作目录及其子目录中的所有文件。

通常,每行都以文件名作为前缀。 -h禁用此行为,以便仅打印行。

>是重定向,并将grep的输出保存在文件global.styl中。

误报

请注意,import .*\.styl只是一个字符串搜索。会匹配

import 'something/something.styl';

而且

s = "not an import a; just.a.string.with.style.";

您可以优化表达式以使其更精确,但在大多数情况下并不需要。

删除重复项

如果相同的import多次出现(例如在不同的文件中),则您可能希望删除重复项,使global.styl

import 'a.styl';
import 'b.styl';

代替

import 'b.styl';
import 'a.styl';
import 'a.styl';
import 'b.styl';
...

为此,您可以使用

grep -hr 'import .*\.styl' | sort -u > global.styl

转换相对路径

如果从目录dir1开始,并且文件dir1/dir2/dir3/file包含import './path/file.styl';,则可能要将相对导入转换为import './dir2/dir3/path/file.styl';。以下命令是一种快速而肮脏的解决方案(您可以将其编写为一行):

grep -r 'import .*\.styl' |
sed -E 's,(.*/)*.*:(.*)(\./),\2./\1,;s,.*:,,' > global.styl

此解决方案将./替换为文件目录。不包含./的路径将不被处理。我们假定路径从不包含:或某些以.结尾的组件(例如some./path)。