Scripting on Windows
There’s this flame war between Linux and Windows. Like Linux is user-friendly, it’s just more selective with its friends. Another one is, that it’s easy if you don’t mind clicking. Windows 10 contains a bash shell, still, this won’t end just now.
So, there is this flame war, old and still funny. But this post is about something else. I’m trying to explain why I always install a cygwin / mingw on a corporate windows box.
Obviously, I install them because we’re not using Windows 10 yet. Also, I’m installing mingw because git-bash is based on that. Still, this isn’t the real reason.
Why is it useful?
The real reason is that I can solve complex problems quickly. Say for instance, the jd-gui had some problems. It couldn’t decompile some classes and it wouldn’t save all the decompiled sources either. I could’ve downloaded some other versions and played with them. However, I already had mingw and procyon on my machine so I started to write a for loop. In a couple of minutes I had this:
cp -r classes sources # this creates a paralel directory structure
find sources -name '*.class' | xargs rm # this removes the class files
# a for loop through the classes. I could've excluded the inner classes too..
for f in `find classes -name '*.class'`; do
# creating the name of the destination java file
j=`echo $f | sed -e 's/^classes/sources/g' -e 's/.class$/.java/g'`;
# invoking the decompiler
java -jar /f/Programs/decompilers/procyon-decompiler-0.5.30.jar $f > $j;
The point here isn’t the code. Bash can do loops, branches, and other stuff in a weird way. The point is that I could substitute some gui functionality with some code in a couple of minutes. It took as much as starting up eclipse and creating a new project.
It’s not only useful. Writing code seeing it run instantly – it’s almost magical. Others might prefer the REPL for Lisp, python, powershell or ruby. Still, bash is the most ubiquitous from all above.
So, I wrote this one-time script. There are a few enhancements I could’ve made.
I.e. this is how you can filter out the inner classes from the decompiler loop:
for f in `find classes -name '*.class' | grep -v '\$'`; do
But deleting them isn’t much harder either:
find . -name '*.java' | grep '\$' | xargs rm
I can also mass-edit the decompiled classes:
# a loop for the java sources
for j in `find src/ -name '*.java'`; do
# retrieving the java class name from the path
f=`echo $j | sed -e 's/^.*\///g' -e 's/.java$//g'`;
# creating the command - it will be useful for debugging
cmd=`echo "sed -i 's/\b$f\.//g' $j"`;
echo $cmd; # some feedback during the script run
eval $cmd; # invoking the actual command
As you can see, I’m using sed and command substitution extensively. There might be other approaches that I’m unfamiliar with. Still, these tools help me a lot to solve complex problems quickly.
What now? We can follow @climagic. We can learn how to parametrize procyon to do what we want. I could learn awk.
What are your favorite command-line tools? How could you improve these scripts?