diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,1 @@
+batch-rename is Public Domain
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# batch_rename
+A simple command make linux or macos do things like "rename *.mp3 *.mp4" in Windows/MSDOS
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/batch-rename.cabal b/batch-rename.cabal
new file mode 100644
--- /dev/null
+++ b/batch-rename.cabal
@@ -0,0 +1,81 @@
+-- Initial batch-rename.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                batch-rename
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- http://www.haskell.org/haskellwiki/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            Make linux or macos do things like "rename *.mp3 *.mp4" in Windows/MSDOS
+
+-- A longer description of the package.
+description:      Do you remember the convenient command `rn' in MSDOS ?
+                  When you want to change all your .mp3 files to .mp4
+                  Simply type rn *.mp3 *.mp4.
+                  I really like this.
+                  But in linux/Mac world, people keep asking how.(http://bit.ly/2cIskUu)
+                  So maybe this little tool can help you a lot. QUOTE NEEDED.
+                  Example:
+                    batch_rename "*.mp3" "*.mp4"
+                    batch_rename "*.mp3" "fake*.mp4"
+                    batch_rename "DCIM*.jpg" "*.png"
+
+-- URL for the project homepage or repository.
+homepage:            https://github.com/uppet/batch_rename
+
+-- The license under which the package is released.
+license:             PublicDomain
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Joyer Huang
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          collger@gmail.com
+
+-- A copyright notice.
+-- copyright:           
+
+category:            System
+
+build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or a 
+-- README.
+extra-source-files:  README.md
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.10
+
+
+executable batch_rename
+  -- .hs or .lhs file containing the Main module.
+  main-is:             batchRename.hs
+  
+  -- Modules included in this executable, other than Main.
+  -- other-modules:       
+  
+  -- LANGUAGE extensions used by modules in this package.
+  -- other-extensions:    
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base >=4.6 && <4.7,
+                       Glob >=0.7.11,
+                       filepath >=1.1,
+                       directory
+  -- Directories containing source files.
+  -- hs-source-dirs:      
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
diff --git a/batchRename.hs b/batchRename.hs
new file mode 100644
--- /dev/null
+++ b/batchRename.hs
@@ -0,0 +1,46 @@
+import Data.List
+import System.Directory
+import System.Environment
+import System.FilePath.Glob
+import System.FilePath.Posix
+
+usage :: IO ()
+usage = do progName <- getProgName
+           putStrLn ("Usage:\n\t" ++ progName ++ " \"srcPattern\" \"dstPattern\"")
+
+hasWildcard :: [Char] -> Bool
+hasWildcard name = 1 == (length $ filter (\x -> x == '*') name)
+
+bruteIndex e l = case (elemIndex e l) of
+                   Just x -> x
+                   Nothing -> 0
+
+trimHeadTail s pre pos = let
+  nohead = drop (length pre) s in
+    reverse (drop (length pos) (reverse nohead))
+
+
+partRename preL posL preR posR name = 
+  let fn = takeFileName name in
+  renameFile fn (preR ++ (trimHeadTail fn preL posL) ++ posR)
+
+batchRename :: [Char] -> [Char] -> IO ()
+batchRename left right = if hasWildcard left && hasWildcard right then
+                           let wildcardLeftIndex = bruteIndex '*' left
+                               oldPreLeft = take wildcardLeftIndex left 
+                               oldPosLeft = drop (wildcardLeftIndex + 1) left
+                               wildcardRightIndex = bruteIndex '*' right
+                               oldPreRight = take wildcardRightIndex right
+                               oldPosRight = drop (wildcardRightIndex + 1) right in
+                             do files <- glob left
+                                sequence_ (map (partRename oldPreLeft oldPosLeft
+                                                          oldPreRight oldPosRight)
+                                               files)
+                         else
+                           putStrLn "Oops, use simple rename please."
+main :: IO ()
+main = do args <- System.Environment.getArgs
+          case args of
+            [l,r] -> batchRename l r
+            otherwise -> usage
+
