Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# scripts

A collection of scripts that contain useful utilities and functions.
A collection of scripts that contain useful utilities and functions.
Most scripts are written for bash/zsh shell in mind, although some are Ruby files which will need the Ruby interpreter to function.

On Linux, run `setup.sh` with admin privileges to automatically copy over shell scripts into `/usr/local/bin`.
On Linux, run `setup.sh` with admin privileges to automatically copy over these scripts into `/usr/local/bin`.
5 changes: 3 additions & 2 deletions setup.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
for file in src/*.sh; do
cp "$file" "${file%.sh}"
for file in src/*.{sh,rb}; do
[ -e "$file" ] || continue
cp "$file" "${file%.*}"
done
66 changes: 66 additions & 0 deletions src/sharpener.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env ruby

require "find"
require "openssl"

$duplicates_increment = 0
$files_increment = 0

##
# Logs progress finding duplicates to stdout.
#
# @param is_duplicate A boolean indicating if the progress to be logged includes a duplicate file or not.
def log_duplicate_progress(is_duplicate:)
$duplicates_increment += 1 if is_duplicate

print "\r#{$duplicates_increment} duplicates / #{$files_increment} files scanned"
$files_increment += 1
end

##
# Finds all duplicates—recursively—within the supplied target directory. Ignores any directories or files that are
# prefixed with a period character.
#
# @param target The string that represents the path to the target directory.
#
def find_dupes(target)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this multi-threaded.

duplicates = {}

Find.find(target) do |path|
Find.prune if File.basename(path).start_with?(".")

if FileTest.file?(path)
digest = OpenSSL::Digest::SHA256.file(path).hexdigest

log_duplicate_progress(is_duplicate: duplicates.key?(digest))

duplicates[digest] = [] unless duplicates.key?(digest)
duplicates[digest] << path
end
end

STDOUT.puts "\n==="
duplicates.select { |k, v| v.size > 1 }.each do |k, v|
STDOUT.puts "duplicate: #{k}"
STDOUT.puts "#{v}"
end
end

##
# Given a source directory, find all files in source directory that are not present in the target directory. Ignores any
# directories or files that are prefixed with a period character.
#
# @param source
# @param target
#
def find_unqiues(source, target); end

case ARGV[0]
when "duplicates"
find_dupes(ARGV[1])
when "uniques"
find_uniques(ARGV[1], ARGV[2])
else
STDERR.puts "Please provide either 'duplicates' or 'uniques' to 'sharpener'."
exit(1)
end