Skip to content

Instantly share code, notes, and snippets.

@WaterSibilantFalling
Created September 21, 2017 14:03
Show Gist options
  • Save WaterSibilantFalling/935bdbac64a744025b0be5ea65ed7cae to your computer and use it in GitHub Desktop.
Save WaterSibilantFalling/935bdbac64a744025b0be5ea65ed7cae to your computer and use it in GitHub Desktop.
removes spaces and difficult characters from all the files in the local directory, or from one single file
#!/usr/bin/perl
# This program removes spaces and crap from *nix filenames
#
use common::sense;
my $shitReplaceChar = '_'; # use this car in place of the removed junk characters
use autodie;
use charnames qw< :full >;
use File::Basename qw< basename >;
use Carp qw< carp croak confess cluck >;
use POSIX;
use English qw( -no_match_vars ) ;
END { close STDOUT }
$0 = basename($0); # shorter messages
$| = 1; # autoflush: solving perl's stupidities 1 by 1
# --- unicode ---
binmode STDOUT, ":encoding(UTF-8)";
binmode STDERR, ":encoding(UTF-8)";
use Unicode::Normalize qw< NFD NFC >;
use Encode qw< encode decode >;
# --- commandline parametes ---
use Getopt::Long qw(:config no_ignore_case bundling);
my $inglob = "/dev/null";
GetOptions( "i:s" => \$inglob # optional infile
);
# --- Useage message
my $usageMsg = <<USAGE;
rs #process all files in current dir
rs [--i=my_file_name.txt] # optional single file
rs [--i=*cats.*4] # an optional glob
• rs removes spaces and other non-*nix crap from filenames
• The optional --i will be used in `ls -1b ` to collect
files to process
USAGE
# --- test the commandline input
# a commandline parameter, but no --inglob ?
if (($inglob eq "/dev/null") && (@ARGV == 1)){
print $usageMsg;
exit(1);
}
# excess parameters ?
if ($#ARGV > 1) {
print $usageMsg;
exit(1);
}
# # OK doing the whole directory
# $inglob = "*"
# if ($inglob eq "/dev/null");
#----- file processing loop
my @filesToProcess = ();
if ($inglob eq "/dev/null") {
@filesToProcess = `ls -1d *`;
} else {
@filesToProcess = `ls -1d "$inglob"`;
}
# -d : don't descend, list Dir contents, not the contents' contents.
chomp @filesToProcess;
foreach my $thisFn (@filesToProcess) {
my $newFn = $thisFn;
$newFn =~ s,[\'#\\!\[\]!\(\) \-\,&]+,$shitReplaceChar,g;
next
if ($thisFn eq $newFn);
# also, some chars have to be escaped
my $escapedThisFn = ($thisFn =~ s,([\(\)\'\!\& ]),\\$1,gr);
say "$escapedThisFn\t\tto\t\t$newFn";
`mv $escapedThisFn "$newFn" `;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment