2017-12-29 25 views
0
#!/bin/sh 
for file1 in directorypath/* 
do 
    for file2 in directorypath/* 
     do 
       if [ "$file1" = "$file2" ]; then 
         echo "files are same" 
       else 


           cp /dev/null /home/temp.txt 
       grep -f $file1 $file2 > /home/common.txt 
       grep -v -x -f /home/common.txt $file1 > /home/temp.txt 
           cp /dev/null $file1 
           cat /home/temp.txt >> $file1 


           cp /dev/null /home/temp.txt 
       grep -v -x -f /home/common.txt $file2 > /home/temp.txt 
           cp /dev/null $file2 
       cat /home/temp.txt >> $file2 

       fi; 
     done 
done 

Dieser Code funktioniert gut für Dateien kleiner Größe. Da ich große Textdateien verarbeiten muss, nimmt dieser Code selbst auf dem Server viel Zeit in Anspruch. Bitte helfen! Wie erreiche ich dasselbe effizient? Vielen Dank im Voraus.Wie werden nur einzelne Wörter aus einer Datei entfernt, die nicht mit anderen Wörtern in Dateien (zwei oder mehr Dateien) übereinstimmen?

+0

Wenn ich Ihren Code richtig verstehen: 1 - Sie haben ein Verzeichnis von Dateien. 2 - Sie möchten jede Datei in eine Datei umwandeln, die nur für diese Datei eindeutige Wörter enthält. Interessieren Sie sich für die Implementierungssprache (würde es Ihnen etwas ausmachen, ein Python-Skript auszuführen? Möchten Sie die Reihenfolge der Wörter in der Datei beibehalten? – entropy

+0

) Wie groß sind Ihre Dateien? ein Problem, um alle Dateien im Speicher auf einmal zu halten? – entropy

+0

danke @entropy 1. Es gibt keine Einschränkung der Sprache, 2. Kein Problem der Bestellung auch. Ich habe fast 35 Textdateien jeweils 300 MB. Ich glaube nicht Es ist möglich, alle Dateien in den Speicher zu laden (nicht sicher) –

Antwort

0

Versuchen Sie, diese Python-Skript (das Verzeichnis als Argument):

import sys 
import os 

# Keeps a mapping of word => file that contains it 
# word => None means that that word exists in multiple files 
words = {} 

def process_line(file_name, line): 
    try: 
     other_file = words[line] 
     if other_file is None or other_file == file_name: 
      return 
     words[line] = None 
    except KeyError: 
     words[line] = file_name 

file_dir = sys.argv[1] 
for file_name in os.listdir(file_dir): 
    with open(os.path.join(file_dir, file_name)) as fd: 
     while True: 
      line = fd.readline() 
      if len(line) == 0: 
       break 
      line = line.strip() 
      if len(line) == 0: 
       continue 
      process_line(file_name, line) 

file_descriptors = {} 
# Empty all existing files before writing out the info we have 
for file_name in os.listdir(file_dir): 
    file_descriptors[file_name] = open(os.path.join(file_dir, file_name), "w") 

for word in words: 
    file_name = words[word] 
    if file_name is None: 
     continue 
    fd = file_descriptors[file_name] 
    fd.write("%s\n" % word) 

for fd in file_descriptors.values(): 
    fd.close() 

Anforderung Speicher:

Sie müssen im Speicher auf einmal alle eindeutigen Worte halten zu können. Angenommen, es gibt viele Duplikate zwischen Dateien, sollte dies machbar sein. Ansonsten sehe ich ehrlich gesagt keinen Ansatz schneller als das, was Sie bereits haben.

Wenn Sie nicht in der Lage sind, alles Notwendige in den Speicher zu packen, werfen Sie einen Blick auf this answer für mögliche Wege, eine Disk-basierte Lösung für das Diktat zu verwenden, anstatt alles im Speicher zu halten. Ich habe keine Ahnung, wie viel das die Leistung beeinflussen wird und ob es an diesem Punkt noch schnell genug laufen wird.

Warum ist es schneller? (In der Theorie ungetestet)

Es macht nur einen einzigen Durchgang durch jede Datei und fertig. Ihr aktueller Ansatz ist O(n^2) wo n ist die Anzahl der Dateien

+0

Vielen Dank! Es funktioniert in sehr kurzer Zeit. –

+0

Ich bin froh, Ihnen helfen zu können – entropy

Verwandte Themen