首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >awk sed -将文本与文件进行比较,搜索字符串,在同一文件中查找重复的实例,在EOL添加一些文字

awk sed -将文本与文件进行比较,搜索字符串,在同一文件中查找重复的实例,在EOL添加一些文字
EN

Stack Overflow用户
提问于 2012-10-03 21:46:05
回答 1查看 707关注 0票数 1

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

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

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

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

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

file1

代码语言:javascript
复制
\\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上列出,并且我想在行尾(已经包含在另一个文件夹上的行)添加一些单词,例如: Physical path is a subfolder of Line#

所需输出:

代码语言:javascript
复制
\\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;

我做了什么:

代码语言:javascript
复制
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

我不想创建一个名为file1.csv的新文件,我希望将所有数据都倾倒到原始文件中: dupli.txt 1.csv,因此我的解决方案不适用于我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-04 04:32:07

虽然您可以使用sed来实现这一点,但我认为awk就是为此而构建的。

如果你的文本文件很长,那么我认为在两次遍历中做这件事是最有意义的,这样你就不必把整个文件加载到内存中。

首先,你会得到一个潜在父母的列表:

代码语言:javascript
复制
awk -F\; '{print $3}' file1 > paths.txt

现在将其读入数组,并将其与文件中的其他行进行比较。我将该文件命名为pathrefs.awk.命令行应该是:

代码语言:javascript
复制
awk -f pathrefs.awk paths.txt file1

pathrefs.awk的内容是:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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;;;;;;;;;;;

下面是脚本生成的输出:

代码语言:javascript
复制
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:"

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12709865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档