从文件的多行中删除带有重复字符串的行

时间:2013-02-11 11:09:55

标签: linux

我有一个包含许多此类行的文件,其中包含一些文件的路径。

../../ds1_src/wrapper/memory/beh/mem_1w1r_8x160.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_8x134.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_8x178.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_20x68.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_280x128.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_8x160.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_8x134.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_64x7.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_24x128.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_8x178.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_20x68.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_280x128.v
../../ds3_src/wrapper/memory/beh/mem_1w1r_1x160.v
../../ds3_src/wrapper/memory/beh/mem_1w1r_1x128.v
../../us_src/wrapper/memory/beh/mem_1w1r_128x8.v
../../us_src/wrapper/memory/beh/mem_1w1r_8x160.v
../../us_src/wrapper/memory/beh/mem_1w1r_8x178.v
../../us_src/wrapper/memory/beh/mem_1w1r_20x68.v
../../us_src/wrapper/memory/beh/mem_1w1r_280x128.v
../../src/sw/mem_1w1r_8x31.v
../../src/sw/mem_1w1r_8x35.v

其中一些是重复文件。

我希望对其进行排序和统一,以便删除重复的文件行。

% grep -r "mem_1w" rtl_list | awk '{split($$0,a,"/"); print a[7]}' | sort -u

我可以执行类似上面的操作来统一文件名 - 但这会导致行../../ds1_src/....等的第一部分被切断。此外,在[5]和../../src/sw/mem_1w1r_8x31.v中都可能存在重复。

mem_1w1r_128x8.v
mem_1w1r_145x133.v
mem_1w1r_1x128.v
mem_1w1r_1x160.v
mem_1w1r_20x68.v
mem_1w1r_24x128.v
mem_1w1r_280x128.v
mem_1w1r_64x7.v
mem_1w1r_73x133.v
mem_1w1r_8x134.v
mem_1w1r_8x160.v
mem_1w1r_8x178.v

我怎样才能解决这个问题 - 得到类似的东西 -

../../ds1_src/wrapper/memory/beh/mem_1w1r_8x160.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_8x134.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_64x7.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_1x160.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_1x128.v

会删除不同位置的任何重复文件吗?

4 个答案:

答案 0 :(得分:1)

这是使用awk的一种方式:

awk -F "/" '/mem_1w/ && !a[$NF]++' file

结果:

../../ds1_src/wrapper/memory/beh/mem_1w1r_8x160.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_8x134.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_8x178.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_20x68.v
../../ds1_src/wrapper/memory/beh/mem_1w1r_280x128.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_64x7.v
../../ds2_src/wrapper/memory/beh/mem_1w1r_24x128.v
../../ds3_src/wrapper/memory/beh/mem_1w1r_1x160.v
../../ds3_src/wrapper/memory/beh/mem_1w1r_1x128.v
../../us_src/wrapper/memory/beh/mem_1w1r_128x8.v
../../src/sw/mem_1w1r_8x31.v
../../src/sw/mem_1w1r_8x35.v

答案 1 :(得分:0)

也许您可以使用python来保持文件名和现有文件路径之间的映射,例如(key,[path1,path2 ...])。然后你可以对可能的文件路径进行排序,只使用第一个。

import os.path
import fileinput

# dictonary to hold (key, [path1, path2 ...]) 
file_paths = {}

for line in fileinput.input("input.txt"):
    value = line.strip('\n')
    base = os.path.basename(line)

    if base in file_paths:
      # add another value to existing key
      keys = file_paths[base]
      keys.append(value)
      file_paths[base] = keys
    else:
      # init another bucket
      file_paths[base] = [value]

# print only firt value
for key in file_paths.keys():
    sl = sorted(file_paths[key])
    print sl[0]

答案 2 :(得分:0)

echo > output.txt ; 
while read F; do 
    N=$(basename ${F}); 
    grep $N output.txt 1>/dev/null || echo $F >> output.txt ; 
done 

当然你可以在一条线上做到。

我认为你的输入文件中的输出也不正确(输入中没有所有文件)。

答案 3 :(得分:0)

您可以使用以下命令按名称使列表唯一:

awk -F/ '!F[$NF] && F[$NF]=$0'

这将仅包含具有每个唯一名称的第一个文件的路径。然后,您可以通过sort管道输出结果,但不需要-u选项。

这可以通过在awk中构建数组来实现。每个索引都是没有路径的文件名(-F/选项,文件名只是$NF)。每个元素都是具有该文件名的第一个文件的完整路径(完整路径为$0)。如果以前没有看到文件名,则只添加和打印新的数组条目。