2016-08-24 88 views
2

我在尋找是否有自動執行此過程的方法。基本上我有每天需要下載的30萬行數據。有幾行需要在可以上傳到SQL之前進行編輯。查找並編輯文本文件

Jordan || Michael | 23 | Bulls | Chicago 

Bryant | Kobe ||| 8 || LA 

我想完成的是每行只有4個豎條。通常情況下,我會搜索一個關鍵字,然後手動編輯然後保存。這兩個是我的數據中唯一的異常情況。

  1. 找到「Jordan」,然後刪除多餘的1個豎條「|」緊隨其後。
  2. 我需要找到「神戶」,然後刪除兩個多餘的垂直條「|」緊隨其後。

正確的格式如下 -

Jordan | Michael | 23 | Bulls | Chicago 

Bryant | Kobe | 8 || LA 

不知道這是否可以在VBScript或Python來完成。 任何幫助,將不勝感激。謝謝!

+0

爲什麼8之後仍然有兩個'|'? –

+0

嗨。在上面的例子中,每行總是應該有四個垂直條來分隔每個字段。有些情況下字段可以是空白的,就像上面的例子。 –

回答

2

Python或vbscript可以使用,但它們過於簡單。嘗試sed

$ sed -E 's/(Jordan *)\|/\1/g; s/(Kobe *)\| *\|/\1/g' file 
Jordan | Michael | 23 | Bulls | Chicago 
Bryant | Kobe | 8 || LA 

要保存到一個新文件:

sed -E 's/(Jordan *)\|/\1/g; s/(Kobe *)\| *\|/\1/g' file >newfile 

或者,改變就地現有文件:

sed -Ei.bak 's/(Jordan *)\|/\1/g; s/(Kobe *)\| *\|/\1/g' file 

它是如何工作

的sed逐行讀取和處理文件。在我們的例子中,我們只需要具有s/old/new/g格式的替換命令,其中old是一個正則表達式,如果找到它,則替換爲new。命令結尾的可選g告訴sed執行替換命令「全局」,這意味着不僅僅是一次,而是多次出現在行上。

  • s/(Jordan *)\|/\1/g

    這告訴sed尋找喬丹後跟零個或多個空格,然後豎線和刪除豎線。

    更詳細地說,(Jordan *)中的parens告訴sed保存字符串Jordan,後跟零個或多個空格作爲一個組。在替換方面,我們將該組引用爲\1

  • s/(Kobe *)\| *\|/\1/g

    同樣,這告訴sed找科比後跟零個或多個空格,然後豎線和刪除豎線。

使用Python

使用與上述相同的邏輯,這裏是一個Python程序:

$ cat kobe.py 
import re 
with open('file') as f: 
    for line in f: 
     line = re.sub(r'(Jordan *)\|', r'\1', line) 
     line = re.sub(r'(Kobe *)\| *\|', r'\1', line) 
     print(line.rstrip('\n')) 
$ python kobe.py 
Jordan | Michael | 23 | Bulls | Chicago 
Bryant | Kobe | 8 || LA 

要的是保存到一個新的文件:

python kobe.py >newfile 
+0

嗨,哇!只需幾行代碼。我對sed不熟悉,是否可以在Windows中運行?謝謝! –

+0

@JamesVici在Windows上安裝'sed'有很多種方法。我知道它是例如Cygwin,GNUWin32和msys包的一部分。或者,我只是用Python代碼更新了答案。 – John1024

+0

你們是這個名字的鑰匙,記得他有30萬行的名字。 –

1

我寫的Python 3.5中的代碼片段如下。

# -*- coding: utf-8 -*- 

rows = ["Jordan||Michael|23|Bulls|Chicago", 
     "Bryant|Kobe|||8||LA"] 

keywords = ["Jordan", "Kobe"]   

def get_keyword(row, keywords): 
    for word in keywords: 
     if word in row: 
      return word 
    else: 
     return None    

for line in rows: 
    num_bars = line.count('|') 
    num_bars_del = num_bars - 4 # Number of bars to be deleted 
    kw = get_keyword(line, keywords) 
    if kw: # this line contains a keyword 
     # Split the line by the keyword 
     first, second = line.split(kw) 
     second = second.lstrip() 
     result = "%s%s%s"%(first, kw, second[num_bars_del:]) 
     print(result)