Skip to content

Instantly share code, notes, and snippets.

@wisq
Last active April 9, 2020 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wisq/01dfd712caf32d09e13b53ddaa2de5c9 to your computer and use it in GitHub Desktop.
Save wisq/01dfd712caf32d09e13b53ddaa2de5c9 to your computer and use it in GitHub Desktop.
Quick and dirty Elixir script to fix filenames with invalid unicode
#! /usr/bin/env elixir
defmodule Fixer do
def parse_args(["-n" | args]), do: {false, args}
def parse_args(["-f" | args]), do: {true, args}
def parse_args(args), do: {false, args}
def fix_all({rename, files}) do
{:ok, stdout} = File.open("/dev/stdout", [:write])
Process.register(stdout, :stdout_binary)
Enum.each(files, &fix_directory(rename, &1))
File.close(stdout)
end
defp fix_directory(rename, path) do
{:ok, entries} = :file.list_dir_all(path)
Enum.each(entries, &fix_entry(rename, path, &1))
end
defp fix_entry(rename, path, file) when is_list(file) do
# Since file is a charlist, it's valid unicode.
file_str = List.to_string(file)
target = Path.join(path, file_str)
maybe_fix_directory(rename, target)
end
defp fix_entry(rename, path, file) when is_binary(file) do
# Since file is a binary, it's NOT valid unicode.
new_file = clean(file)
source = Path.join(path, file)
target = Path.join(path, new_file)
IO.binwrite(:stdout_binary, "<= #{source}\n=> #{target}\n\n")
if rename do
File.rename!(source, target)
maybe_fix_directory(rename, target)
else
maybe_fix_directory(rename, source)
end
end
defp maybe_fix_directory(rename, path) do
case File.lstat(path) do
{:ok, %File.Stat{type: :directory}} -> fix_directory(rename, path)
{:ok, %File.Stat{}} -> :noop
end
end
defp clean(""), do: ""
defp clean(<<head, rest::binary>>) when head <= 127, do: <<head>> <> clean(rest)
defp clean(<<head, rest::binary>>) when head > 127, do: "?" <> clean(rest)
end
System.argv()
|> Fixer.parse_args()
|> Fixer.fix_all()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment