users.csv
ユーザー名、ユーザーID、およびその他のデータのリストを含むCSVファイルがあります。
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"Paul McCartny", 30923833, "left", "black"
"Ringo Starr", 77392318, "right", "blue"
"George Harrison", 72349482, "left", "green"
他のファイルにはtoremove.txt
ユーザーIDのリストがあります。
30923833
77392318
users.csv
ファイルからIDを含むすべての行を削除するスマートで効率的な方法はありますかtoremove.txt
?私はこれらの2つのファイルを解析し、新しいファイルにない行だけを書く単純なPythonアプリケーションを書いたが、toremove.txt
非常に遅い。たぶんsed
魔法はawk
ここに役立つでしょうか?
上記の例を考慮すると、望ましい結果は次のとおりです。
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"George Harrison", 72349482, "left", "green"
答え1
を使用すると、grep
次のことができます。
$ grep -vwF -f toremove.txt users.txt
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"George Harrison", 72349482, "left", "green"
そしてawk
:
$ awk -F'[ ,]' 'FNR==NR{a[$1];next} !($4 in a)' toremove.txt users.txt
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"George Harrison", 72349482, "left", "green"
答え2
awk
空間盲のために修正されたGnoucの答えは次のとおりです。
awk -F, 'FNR==NR{a[$1];next} !(gensub("^ *","",1,$2) in a)' toremove.txt users.csv
区切り文字としてはスペース以外のカンマのみを使用するため、対応するスペース(ユーザーID)がファイルに存在することを確認する前に、先行スペースを削除してください$1
。"John Lennon"
$2
90123412
gensub
$2
toremove.txt
答え3
良いルビー方法:あるファイルに文字列リストがあり、別のファイルのすべての行を削除したい場合含む最初のファイルの文字列(この場合は「file1」から「file2」を削除)Rubyファイル:
b=File.read("file2").split # subtract this one out
remove_regex = Regexp.new(b.join('|'))
File.open("file1", "r").each_line do |line|
if line !~ remove_regex
puts line
end
end
残念ながら、これは「削除する」大きなファイルの複雑さをO(N ^ 2)に減らすようですが(私の仮定は正規表現が行うことが多いと仮定しています)、まだ誰かに役立つかもしれません(もし行全体を削除する以上のものが欲しい)場合によってはより速いかもしれません。
速度を追求する場合、別のオプションは同じハッシュチェックメカニズムを使用することです。ただし、一致する文字列があるかどうかを注意深く「構文解析」してから、ハッシュと比較します。
Rubyでは、次のように見えます。
b=File.read("file2").split # subtract this one out
hash={}
for line in b
hash[line] = 1
end
ARGF.each_line do |line|
ok = true
for number in line.scan(/\d{9}/)
if hash.key? number
ok=false
end
end
if (ok)
puts line
end
end
ここで提案されているawkの回答に似ており、O(N ^ 2)の複雑さ(休)を避けるScottの回答も参照してください。