1

我有一个大文本文件,其中包含类似的条目

我的目标是确定是否存在父文件夹,我的意思是,例如 /FS7_100x/FILE04 是否是该文件夹的父文件夹:/FS7_100x/FILE04/BU-D/PROJECT CONTROL OFFICE

这两条路径之间的关系是它们在某些时候共享相同的路径。我为什么要这样做?因为这样做我知道该路径使用的空间是否已经计入父文件夹。

第三个字段填充了文件系统路径,我想将每行上的每个路径与同一个文件、相同的第三个字段进行比较,在路径的末尾添加一个斜杠 /。这意味着:比较:/FS7_100x/FILE04/BU-D/PROJECT CONTROL OFFICE 与 /FS7_100x/FILE04/BU-D/PROJECT CONTROL OFFICE & /FS3_200g/FILE12/BU/AGENCY/GOLDMINE & /FS3_200g/FILE12

例如,我想查找 /FS7_100x/FILE04/ 和 /FS3_200g/FILE12/

文件 1

\\FILE04\BUET-PCO;\\SERVER24\OFFICE;/FS7_100x/FILE04/BU-D/PROJECT CONTROL;
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\GOLDMINE;/FS3_200g/FILE12/BU/AGENCY/GOLDMINE;
\\x\a$;\\SERVER24\DFS\somethingelse;/FS3_200g/FILE12;
\\z\o;\\SERVER24\DFS\blah;/FS7_100x/FILE04;

字段用“;”分隔

通过这种方式,我可以确定父文件夹已经列在 file1 上,并且我想在行尾添加一些单词(该行已经包含在另一个行中),例如说:物理路径是 Line 的子文件夹#

所需的输出:

\\FILE04\BUET-PCO;\\SERVER24\OFFICE;/FS7_100x/FILE04/BU-D/PROJECT CONTROL;Physical path is a subfolder of Line#4
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\GOLDMINE;/FS3_200g/FILE12/BU/AGENCY/GOLDMINE;Physical path is a subfolder of Line#3
\\x\a$;\\SERVER24\DFS\somethingelse;/FS3_200g/FILE12;
\\z\o;\\SERVER24\DFS\blah;/FS7_100x/FILE04;

我做了什么:

setlocal enableextensions 
del lugares.csv
for /f "tokens=1,2,3 delims=;" %%i in (file1.csv) do (
for /f "tokens=*" %%p in ('findstr /N /i /r /C:"%%k/" file1.csv') do (
echo Original %%k;%%i;%%j; --- repeated with Line# %%p >>dupli.txt
)
)
pause

我不想创建一个名为 dupli.txt 的新文件,我希望将所有数据倒入原始文件:file1.csv,因此我的解决方案对我不起作用。

4

1 回答 1

2

虽然您可以使用sed它,但我认为这是为之而生的东西awk

如果您的文本文件很长,那么我认为分两遍执行此操作最有意义,这样您就不必将整个内容加载到内存中。

首先,您会得到一份潜在父母的名单:

awk -F\; '{print $3}' file1 > paths.txt

现在您将其读入一个数组,并将其与文件中的其他行进行比较。我调用了文件pathrefs.awk。命令行将是:

awk -f pathrefs.awk paths.txt file1

的内容pathrefs.awk是:

BEGIN {
        FS=";"
}

# First, process the paths.txt file...
NR==FNR {
        paths[$0"/"]=NR;
        next;
}

# Next, process the second file, using data gathered from the first file.
{
        delete ref;

        # Make a reference list of paths that match the current line's $3
        for (i in paths) {
                if (index($3,i)==1) {
                        ref[paths[i]];
                }
        }

        # If we found anything...
        if (length(ref)) {
                 $0=$0 "Parent:";
        }

        # Show the list.
        for (i in ref) {
                $0=$0 " #" i;
        }
}

# This is short-hand for "print;"
1

这是我使用的示例输入数据:

this;abcde;/FS7_100x/FILE04/BU-D/PROJECT CONTROL OFFICE;;;;;;;;;;
that;bcdef;/FS3_200g/FILE12/BU/AGENCY/GOLDMINE;;;;;;;;;;;
foo;cdefg;/FS3_200g/FILE12;;;;;;;;
bar;defgh;/FS7_100x/FILE04;;;;;;;;;;;
baz;efghi;/FS7_100x/FILE04/BU-D;;;;;;;;;;;

这是脚本生成的输出:

this;abcde;/FS7_100x/FILE04/BU-D/PROJECT CONTROL OFFICE;;;;;;;;;;Parent: #4 #5
that;bcdef;/FS3_200g/FILE12/BU/AGENCY/GOLDMINE;;;;;;;;;;;Parent: #3
foo;cdefg;/FS3_200g/FILE12;;;;;;;;
bar;defgh;/FS7_100x/FILE04;;;;;;;;;;;
baz;efghi;/FS7_100x/FILE04/BU-D;;;;;;;;;;;Parent: #4

请注意,我已经更改了您在问题中指定的措辞,以便结果在 StackOverflow 上显示得更好。用你喜欢的任何东西代替"Parent:".

如果您认为您可以处理将整个文件加载到内存中的内存要求,那么您可以将整个过程写入单个脚本。到目前为止,我所写的内容描述了您将采用的逻辑。

于 2012-10-03T20:32:07.280 回答