Three Tips for the Linux Shell Addict
Written by Nikos Vaggalis   
Wednesday, 17 May 2017

This time around we have three great tips for the Linux shell addict, three sites that will increase your productivity and save valuable time in your daily interactions with the shell.

The first one is It's a shell snippet search engine where you get to  describe the task you are after in natural English and in return be presented with closely related snippets.



For example, in looking up "How to list only files?", will bring up:

Bash: How to list only files?

  • find . -maxdepth 1 -type f
  • ls -l | egrep -v '^d'
  • ls -l | grep -v '^d'


List only common parent directories for files

DIR=$(dirname "$FIRSTLINE")

while read -r NEXTLINE; do
  until [[ "${NEXTLINE:0:${#DIR}}" = "$DIR" || "$DIR" = "/" ]]; do
    DIR=$(dirname "$DIR")

echo $DIR


How to list files in directory using bash?

for file in /source/directory/*
    if [[ -f $file ]]; then
        #copy stuff ....

Whereas in looking up "How to copy a directory recursively?", will bring up:

How to find files recursively by file type and copy them to a directory while in ssh?

  • find . -name "*.pdf" -type f -exec cp {} ./pdfsfolder \;
  • ssh user@ip.addr 'find -type f -name "*.pdf" -exec cp {} ./pdfsfolder \;'
  • find . -name "*.*" -type f -exec cp {} ./pdfsfolder \;


Copy nested folders contents to one folder recursively (terminal)

  • tar cvfp `find . -name "*.jpg"` | (cd <newfolder>; tar xfp -);
  • cp `find . -name "*.jpg"` <newfolder>;
  • find . -type f -name \*.jpg -exec cp \{\} $TARGETFOLDER \;

Or, in "replace a piece of text in a number of files"

  • sed -i 's/old_link/new_link/g' file...
  • perl -p -i -e <regex> <folder>

The second is This search engine takes the exact opposite approach to ok-borg in that you get to type a shell command or sequence of commands and let explainshell parse them into their raw tokens and explain each one according to its man entry. Useful when finding snippets online but have no idea on what they do.

For example looking up :

"find . -type f -print0", returns:


"find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+"
among others, has this to say on the \+ part , straight from find's man entry:

-exec command {} +
       This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations  of       the command will be much less than the number of matched files.  The command line is built in much the same way that xargs builds its command lines.  Only one instance of `{}' is allowed within the        command.  The command is executed in the starting directory.

The last one is purpose is educational in that it assigns you challenges in order to sharpen your skills but can also act as a good host of snippets in a variety of tasks.

There's a limited number of challenges which require you to type the correct command in the interactive web based shell.

For example the challenge on

"# Print the current working directory"

requires typing pwd next to bash(0)>

If you get that right then it continues asking you to complete more 'difficult' challenges:

# You have a new challenge!
# List names of all the files in the current
# directory, one file per line.

You can find all answers to all the challenges in the "See user submitted solutions for this challenge" area, which in this case will bring up a number of alternatives :

ls *
ls .
ls -c
ls -b
ls -k
ls ./
ls -h
ls -r
echo *
ls |more
ls | cat
echo | ls
echo `ls`
ls -p | grep -v /
ls | awk '{print $1}'
ls --format=single-column
for A in * ;do echo $A;done
find -type f | cut -d'/' -f2
ls -l | awk '{print $NF}' | tail -n +2


as already said, the number of challenges is not great, but nevertheless you can find a few advanced challenges too, for example :

"Print the file faces.txt, but only print the first instance of each
duplicate line, even if the duplicates don't appear next to each other.Note that order matters so don't sort the lines before removing duplicates."

The answer here is more involved :


awk !x[\$0]++ f*
awk '!a[$0]++' f*
awk '!a[$0]++' <f*
<faces* awk '!x[$0]++'
awk '!seen[$0]++' face*
awk !x[\$0]++ faces.txt
awk '!x[$0]++' faces.txt
awk '!i[$0]++' faces.txt
awk '!a[$O]++' faces.txt
awk '!x[$0]++;' faces.txt
awk '!x[$0]++' <faces.txt
awk '!xx[$0]++' faces.txt


Have a nice shell session!



More Information

Related Articles

Wicked Cool Shell Scripts 2nd Ed 

Getting Started With Azure Linux VMs


To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.



TornadoInsight Brings The Power Of TornadoVM Inside Intellij

TornadoInsight is plugin for Jetbrain's popular Intellij IDE for Java developers, that makes working with TornadoVM a much smoother experience.

Anaconda Joins AI Alliance

Anaconda has announced that it is joining the AI Alliance. Anaconda is best known as a provider of open-source distributions of Python and R for scientific computing.

More News

raspberry pi books



or email your comment to:


Last Updated ( Wednesday, 17 May 2017 )