给定所有的redis的键,去掉redis.ini和redisconfig.lua中没有键
lua版本实现
print_r模块
local print_r = {}
function print_r:sub_print_r(t,indent)
if (print_r_cache[tostring(t)]) then
print(indent.."*"..tostring(t))
else
print_r_cache[tostring(t)]=true
if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
print(indent.."["..pos.."] => "..tostring(t).." {")
self:sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
print(indent..string.rep(" ",string.len(pos)+6).."}")
elseif (type(val)=="string") then
print(indent.."["..pos..'] => '..val..'')
else
print(indent.."["..pos.."] => "..tostring(val))
end
end
else
print(indent..tostring(t))
end
end
end
function print_r:print_r ( t )
print_r_cache={}
if (type(t)=="table") then
print(tostring(t).." {")
self:sub_print_r(t," ")
print("}")
else
self:sub_print_r(t," ")
end
print()
end
return print_r;
LIP,引自开源项目
--[[
Copyright (c) 2012 Carreras Nicolas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--]]
--- Lua INI Parser.
-- It has never been that simple to use INI files with Lua.
--@author Dynodzzo
local LIP = {};
--- Returns a table containing all the data from the INI file.
--@param fileName The name of the INI file to parse. [string]
--@return The table containing all data from the INI file. [table]
function LIP.load(fileName)
assert(type(fileName) == 'string', 'Parameter "fileName" must be a string.');
local file = assert(io.open(fileName, 'r'), 'Error loading file : ' .. fileName);
local data = {};
local section;
for line in file:lines() do
local tempSection = line:match('^%[([^%[%]]+)%]$');
if(tempSection)then
section = tonumber(tempSection) and tonumber(tempSection) or tempSection;
data[section] = data[section] or {};
end
local param, value , comment = line:match('^%s*([%w|_]+)%s*=%s*(.+)$');
if(param and value ~= nil)then
if(tonumber(value))then
value = tonumber(value);
elseif(value == 'true')then
value = true;
elseif(value == 'false')then
value = false;
else
local pos = string.find(value,';')
if(not pos) then
pos = #value;
else
pos = pos - 1
end
value = string.sub(value,1,pos);
value = value:match('^(.+)%s*$');
end
if(tonumber(param))then
param = tonumber(param);
end
data[section][param] = value;
end
end
file:close();
return data;
end
--- Saves all the data from a table to an INI file.
--@param fileName The name of the INI file to fill. [string]
--@param data The table containing all the data to store. [table]
function LIP.save(fileName, data)
assert(type(fileName) == 'string', 'Parameter "fileName" must be a string.');
assert(type(data) == 'table', 'Parameter "data" must be a table.');
local file = assert(io.open(fileName, 'w+b'), 'Error loading file :' .. fileName);
local contents = '';
for section, param in pairs(data) do
contents = contents .. ('[%s]\n'):format(section);
for key, value in pairs(param) do
contents = contents .. ('%s=%s\n'):format(key, tostring(value));
end
contents = contents .. '\n';
end
file:write(contents);
file:close();
end
return LIP;
uft-8,引自github上的模块
local m = {} -- the module
local ustring = {} -- table to index equivalent string.* functions
-- TsT 20150916 (v0.3)
-- License: same to the Lua one
-- TODO: copy the LICENSE file
m._VERSION = "lua-utf8 0.3"
m._URL = "https://github.com/tst2005/lua-utf8"
m._LICENSE = 'MIT '
-- my custom type for Unicode String
local utf8type = "ustring"
local typeof = assert(type)
local tostring = assert(tostring)
local string = require("string")
local sgmatch = assert(string.gmatch or string.gfind) -- lua 5.1+ or 5.0
local string_find = assert(string.find)
local string_sub = assert(string.sub)
local string_byte = assert(string.byte)
local table_concat = table.concat
local utf8_object
local function utf8_sub(uobj, i, j)
assert(i, "bad argument #2 to 'sub' (number expected, got no value)")
if i then assert(type(i) == "number") end
if j then assert(type(j) == "number") end
if i == 0 then
i = 1
elseif i < 0 then
i = #uobj+i+1
end
if j and j < 0 then
j = #uobj+j+1
end
local b = i <= 1 and 1 or uobj[i-1]+1
local e = j and uobj[j]
-- create an new utf8 object from the original one (do not "parse" it again)
local rel = uobj[i-1] or 0 -- relative position
local new = {}
for x=i,j,1 do
new[#new+1] = uobj[x] -rel
end
new.rawstring = string_sub(uobj.rawstring, b, assert( type(e)=="number" and e))
new.usestring = uobj.usestring
return utf8_object(new)
end
local function utf8_typeof(obj)
local mt = getmetatable(obj)
return mt and mt.__type or typeof(obj)
end
local function utf8_is_object(obj)
return not not (utf8_typeof(obj) == utf8type)
end
local function utf8_tostring(obj)
if utf8_is_object(obj) then
return obj.rawstring
end
return obj
--return tostring(obj)
end
local function utf8_clone(self)
if not utf8_is_object(self) then
error("it is not a ustring object ! what to do for clonning ?", 2)
end
local o = {
rawstring = self.rawstring,
usestring = self.usestring,
}
return utf8_object(o)
end
--local function utf8_is_uchar(uchar)
-- return (uchar:len() > 1) -- len() = string.len()
--end
-- %z = 0x00 (\0 not allowed)
-- \1 = 0x01
-- \127 = 0x7F
-- \128 = 0x80
-- \191 = 0xBF
-- parse a lua string to split each UTF-8 sequence to separated table item
local function private_string2ustring(unicode_string)
assert(typeof(unicode_string) == "string", "unicode_string is not a string?!")
local e = 0 -- end of found string
local o = {}
while true do
-- FIXME: how to drop invalid sequence ?!
local b
b, e = string_find(unicode_string, "[%z\1-\127\194-\244][\128-\191]*", e+1)
if not b then break end
o[#o+1] = e
end
o.rawstring = unicode_string
o.usestring = #unicode_string == #o
return utf8_object(o)
end
local function private_contains_unicode(str)
return not not str:find("[\128-\193]+")
end
local function utf8_auto_convert(unicode_string, i, j)
assert(typeof(unicode_string) == "string", "unicode_string is not a string: ", typeof(unicode_string))
local obj, containsutf8 = private_string2ustring(unicode_string)
--if private_contains_unicode(unicode_string) then
-- obj = private_string2ustring(unicode_string)
--else
-- obj = unicode_string
--end
return (i and obj:sub(i,j)) or obj
end
local function utf8_op_concat(obj1, obj2)
-- local h
-- local function sethand(o) h = getmetatable(o).__concat end
-- if not pcall(sethand, obj1) then pcall(sethand, obj2) end
-- if h then return h(obj1, obj2) end
return utf8_auto_convert( tostring(obj1) .. tostring(obj2) )
end
local floor = table.floor
local string_char = utf8_char
local table_concat = table.concat
-- http://en.wikipedia.org/wiki/Utf8
-- http://developer.coronalabs.com/code/utf-8-conversion-utility
local function utf8_onechar(unicode)
if unicode <= 0x7F then return string_char(unicode) end
if (unicode <= 0x7FF) then
local Byte0 = 0xC0 + floor(unicode / 0x40)
local Byte1 = 0x80 + (unicode % 0x40)
return string_char(Byte0, Byte1)
end
if (unicode <= 0xFFFF) then
local Byte0 = 0xE0 + floor(unicode / 0x1000) -- 0x1000 = 0x40 * 0x40
local Byte1 = 0x80 + (floor(unicode / 0x40) % 0x40)
local Byte2 = 0x80 + (unicode % 0x40)
return string_char(Byte0, Byte1, Byte2)
end
if (unicode <= 0x10FFFF) then
local code = unicode
local Byte3= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte2= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte1= 0x80 + (code % 0x40)
code = floor(code / 0x40)
local Byte0= 0xF0 + code
return string_char(Byte0, Byte1, Byte2, Byte3)
end
error('Unicode cannot be greater than U+10FFFF!', 3)
end
local function utf8_char(...)
local r = {}
for i,v in ipairs({...}) do
if type(v) ~= "number" then
error("bad argument #"..i.." to 'char' (number expected, got "..type(v)..")", 2)
end
r[i] = utf8_onechar(v)
end
return table_concat(r, "")
end
--for _, n in ipairs{12399, 21560, 12356, 12414, 12377} do print(utf8char(n)) end
--print( lua53_utf8_char( 12399, 21560, 12356, 12414, 12377 ) )
local function utf8_byte(obj, i, j)
local i = i or 1
local j = j or i -- FIXME: 'or i' or 'or -1' ?
local uobj
assert(utf8_is_object(obj), "ask utf8_byte() for a non utf8 object?!")
-- if not utf8_is_object(obj) then
-- uobj = utf8_auto_convert(obj, i, j)
-- else
uobj = obj:sub(i, j)
-- end
return string_byte(tostring(uobj), 1, -1)
end
-- FIXME: what is the lower/upper case of Unicode ?!
-- FIXME: optimisation? the parse is still the same (just change the rawstring ?)
local function utf8_lower(uobj) return utf8_auto_convert( tostring(uobj):lower() ) end
local function utf8_upper(uobj) return utf8_auto_convert( tostring(uobj):upper() ) end
-- FIXME: use the already parsed info to generate the reverse info...
local function utf8_reverse(uobj)
if uobj.usestring then
return utf8_auto_convert(uobj.rawstring:reverse())
end
local rawstring = uobj.rawstring
local tmp = {}
local e = uobj[#uobj] -- the ending position of uchar
-- local last_value = e
-- local o = {} -- new ustring object
for n=#uobj-1,1,-1 do
local b = uobj[n] -- the beginning position of uchar
tmp[#tmp+1] = string_sub(rawstring, b+1, e) -- the uchar
-- o[#o+1] = last_value-b+1
e = b
end
tmp[#tmp+1] = string_sub(rawstring, 1, e)
-- o[#o+1] = last_value
-- o.rawstring = table_concat(tmp, "")
-- return utf8_object(o)
return utf8_auto_convert(table_concat(tmp, ""))
end
local function utf8_rep(uobj, n)
return utf8_auto_convert(uobj.rawstring:rep(n)) -- :rep() is the string.rep()
end
function utf8_object(uobj)
local mt
if not uobj then
uobj = {}
mt = {}
else
mt = getmetatable(uobj) or {}
end
mt.__index = assert(ustring)
mt.__concat = assert(utf8_op_concat)
mt.__tostring = assert(utf8_tostring)
mt.__type = assert(utf8type)
-- mt.__call = function(_self, a1)
-- if a1 == nil then
-- return utf8_clone(_self)
-- end
-- return _self
-- end
return setmetatable(uobj, mt)
end
---- Standard Lua 5.1 string.* ----
ustring.byte = assert(utf8_byte)
ustring.char = assert(utf8_char)
ustring.dump = assert(string.dump)
--ustring.find
ustring.format = assert(string.format)
--ustring.gmatch
--ustring.gsub
ustring.len = function(uobj) return #uobj end
ustring.lower = assert(utf8_lower)
--ustring.match
ustring.rep = assert(utf8_rep)
ustring.reverse = assert(utf8_reverse)
ustring.sub = assert(utf8_sub)
ustring.upper = assert(utf8_upper)
---- custome add-on ----
ustring.type = assert(utf8_typeof)
ustring.tostring = assert(utf8_tostring)
ustring.clone = assert(utf8_clone)
--ustring.debugdump = function(self) return table.concat(self, " ") end
-- Add fonctions to the module
for k,v in pairs(ustring) do m[k] = v end
-- Allow to use the module directly to convert strings
local mt = {
__call = function(_self, obj, i, j)
if utf8_is_object(obj) then
return (i and obj:sub(i,j)) or obj
end
local str = obj
if typeof(str) ~= "string" then
str = tostring(str)
end
return utf8_auto_convert(str, i, j)
end
}
return setmetatable(m,mt)
-------------------------------------------------------------------------------
-- begin of the idea : http://lua-users.org/wiki/LuaUnicode
--
-- for uchar in sgmatch(unicode_string, "([%z\1-\127\194-\244][\128-\191]*)") do
--
--local function utf8_strlen(unicode_string)
-- local _, count = string.gsub(unicode_string, "[^\128-\193]", "")
-- return count
--end
-- http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
处理模块
package.path = package.path ..';../?.lua'
local utf8 = require "lua-utf8.utf8"
local LIP = require "LIP"
local print_r = require "print_r"
local fileName = '/Users/chenpeng9/Desktop/tasks/redisCounter/redis9112.txt';
local deleteFileName = 'delete/redis9112.txt'
local redisini = LIP.load('redis.ini')
local luaRedisIni = require 'redisconfig'
local usedKeys = {};
local deletable = {};
local stay = {};
for section,value in pairs(redisini) do
if(value ~= nil) then
for key,val in pairs(value) do
if(key=='key') then
val = string.gsub(val,'[\'"]',"") --trim ' "
local pos,_d = string.find(val,'%%');
if(pos) then
pos = pos - 1
else
pos = #val;
end
usedKeys[string.sub(val,1,pos)] = true;
end
end
end
end
for key,conf in pairs(luaRedisIni) do
local pos,_d = string.find(conf,'%%');
if(pos) then
pos = pos - 1
else
pos = #conf;
end
usedKeys[string.sub(conf,1,pos)] = true;
end
--print_r:print_r(redisini)
print_r:print_r(usedKeys)
local deleteKeys = ''
local file = assert(io.open(fileName, 'r'), 'Error loading file : ' .. fileName);
local deleteFile = io.open(deleteFileName,'a');
local linecount = 0;
for line in file:lines() do
linecount = linecount + 1;
local keyParsed = line;
keyParsed = string.gsub(keyParsed,'%s+',"")
local pos,endPos = keyParsed:find('(_%d+_?)');
if(not pos) then
pos = #keyParsed
end
keyParsed = keyParsed:sub(1,pos)
if(not usedKeys[keyParsed]) then
deleteKeys = deleteKeys..'\n'..string.gsub(keyParsed,'%s+',"")
if(not deletable[keyParsed]) then
deletable[keyParsed] = 'deletable';
end
else
if(not stay[keyParsed]) then
stay[keyParsed]='stay';
end
end
if(linecount % 10000 == 0){
deleteFile:write(deleteKeys);
deleteKeys = ''
}
end
io.close(deleteFile)
io.close(file);
print '-------deletable------------'
print_r:print_r(deletable)
print '-------deletable end-------'
print '-------to keep -------------'
print_r:print_r(stay)
print '--------to keep end---------'