Using the Terminal – Part 7: Wildcards and Glob Patterns

Using the Terminal – Part 7: Wildcards and Glob Patterns

I have mentioned and used them already a few time, so this time I want to briefly explain the globbing concept in your terminal in more detail.

A glob pattern is pretty similar to a regular expression, but it is simpler. It’s great advantage is, that it is part of the shell and therefor always available. Also the base concepts are shared amongst many operating systems, however, the exact implementation can be different. I don’t want to go into details on this but since I have explained regex before I will explain the difference to them.

In general most commands will only match an exact pattern, so if you want to delete a file, you have to know the file name exactly. rm file.txt will only remove file.txt and no other file that contains the pattern, e.g. file.txt~. However, there are certain characters, that you can insert, to make the pattern less specific. Often these characters are called wildcards or jokers.

Note that bash knows a few options for glob patterns, in the following I will only address the standard *buntu settings. Your .bashrc already contains one option # shopt -s globstar, but it is commented out (so not used and I won’t be using it here as well).

The Asterisk

The asterisk (or star) * stands for an unspecified amount of characters (including zero), that is similar to the asterisk quantifier in regex. To get the same function in regex, you need to combine it with the period .*. Its behavior is identical throughout the various implementations, so you might know it also from Windows. The most likely most popular pattern is *.*.

Examples:

  • a*c – will match every pattern that start with a and ends with c, that is ac as well as abc however, you could also enter whatever you want between a and c
  • *.txt – will match everything that ends with .txt, so in general all txt files

Screenshot from 2015-04-19 17:06:21

As you can see in the example, the definition of the asterisk is pretty weak, so the amount of matches can be fairly large which is making it powerful but also dangerous depending on the command you use. If you just specify the asterisk, your command will match everything. Fortunately, some commands are smart enough too not let you do too much damage, for example rm -rf *.txt will not delete all txt files in all sub directories, but you should really not get more unspecific, rm -rf * is a killer even accidentally added (like rm -rf * *.txt), at least it wont allow you to remove the root directory but still it can do a bit of damage (try using -i with such commands).

The Question Mark

In contrast to the asterisk the ? is very restrictive, it stands for exactly one character, it is equal to the period in regex and not to the question mark. That is a really confusing thing. In regex, the question mark is a quantifier for zero or one, so it has no function by itself, and when combined with the period .? it means something similar but still different (any character zero or one times).

To use the question mark you already have to know pretty well what you are searching for. For example:

  • a?c – will match every pattern that starts with a and ends with c and has exactly one character in between like aac, abc and acc but it would not match ac
  • 2015-03-?? – can be used to match all dates of March 2015

Screenshot from 2015-04-19 17:06:58

However, you can not use the question mark in a way like this *.jp?g to match all files the end on either jpg or jpeg cause it would never match jpg. That makes the biggest difference to regex where the equivalent expression (.*\.jpe?g) can be used for exactly that. Other implementations of glob patterns might handle that differently, there it could mean zero or one.

Square Brackets

The square brackets [] are pretty similar to those known from regex, they define a range of characters. The biggest difference is that regex uses the caret ^ to invert the range while in glob pattern you use the exclamation mark !.

  • a[abc]c – will match ever pattern that starts with a and end with c and has either a, b or c in between, aac, abc, acc but not ac or adc
  • a[a-z]c – will will match ever pattern that starts with a and end with c and has one of the characters a to z between them
  • a[!abc]c – will match all patterns that start with a and end with c expect this with a, b, c or nothing between them, so it will not match ac, aac, abc and acc.

You need to be careful with character ranges like [a-z], it means aAbBcC…z, it will match small and capital letters for everything but the z, so the better range is [a-Z] but [a-zA-Z] should work as well.

Screenshot from 2015-04-19 17:20:49

Curly Brackets

Using curly brackets {} you can define alternatives in a comma separated list, which is pretty similar to (|) in regex. A pattern like {pattern1,pattern2} matches either pattern1 or pattern2. Examples:

  • {ab,bc,ac} – will match either ac, ab or ac
  • a{?,}c – will match any pattern that starts with a and end with c and has exactly one character or none in between, so it will also match ac

Screenshot from 2015-04-19 17:24:11

This last example gets us closer to the behavior of the ? in regex, to search for both jpg and jpeg files one can use *.jp{e,}g, so e? in regex matches {e,} in a glob pattern. Wait, not so fast there is one drawback: *.jp{e,}g will search for *.jpg and *.jpeg, that is okay as long as both are found, if e.g. nothing matches *.jpeg it will produce an error.

You can use the curly brackets also to define character ranges but their use is different. If you type echo {a..z}, the terminal will print all (small) characters from a to z. That sounds good but ls *.t{a..z}t is not the same as ls *.t[a-z]t. It’s the same problem as mentioned above, it will produce error messages for every unsuccessful search.

So, while the curly brackets are expected to have a behavior like an OR they act more like an AND, instead of searching for (pattern1 OR pattern2) it does a search for pattern1 and a search for pattern2. This is called brace expansion, the expansion in brackets gets expanded to all possible patterns and all possible patterns will be searched and if one of these searches fails, it returns an error.

Still this is a nice function, try for example echo {-100..100..5} or echo {a..z..2} and see what happens.

Tl;dr

As you can see from the examples glob patterns are much less flexible than regex patterns which limits their use. However, they are by far not useless because they are a feature of the shell and are available for many commands that do not support regex.

But as always you should be careful in case you are not sure what exactly your pattern will match, in particular with the very unspecific asterisk. If you use such unspecific patterns always use ls to test or make the command interactive.

Using the Terminal – Part 6: Chaining Commands and Writing to Files

Using the Terminal – Part 6: Chaining Commands and Writing to Files

I have already used pipes in some of the previous posts, without going into detail. The terminal knows several way to chain commands, it’s not much different than writing a script where you would do something like this:
command1
command2
command3

you write commands in a sequence you want them to be executed. In this post I want to show a few different ways to chain commands in the terminal and give you a few simple examples, maybe a bit too simple but you can try them without having to fear to break something. These are features of bash, so it might be different in other shells.

Build a simple chain using the ;

The most simple way to chain commands is the semicolon. Calling it an operator is almost a bit too much said cause it is just a separator between two commands. The sequence command1; command2; command3 is the same as the script above, simple example:
cd /; ls
(jump to the root directory then perform ls)
Screenshot from 2015-04-18 15:37:08 or you use
sudo apt-get update; alert
(first check the repo for updates then perform alert).
You can add as many commands as you want, you can even put an entire script in one line. It’s terrible to read but technically possible.

But what happens, if the first command fails? Nothing and that is the problem, the semicolon simply executes the commands one after the other, if, for example, you miss typed the /tmp/ folder in the first command like this
cd /tpm/; ls
Screenshot from 2015-04-18 16:10:23
it will complain about /tpm/ not existing and list the entries of the directory you are currently in. There is no connection between the commands, so you should use this only if the commands can’t do any harm in case the second one is executed without the first one being executed, using it in combination with, e.g., rm can lead to the wrong files being deleted. So be careful when using it.

Build conditional chains using && and ||

Running command1 && command2 also means to perform the first command and then the second, but the second will only be performed if the first was successful (the so called exit state is zero). You can try that with the example above
cd /tpm/ && echo yeah
it will complain about /tpm/ not existing and not perform the echo yeah command.
Screenshot from 2015-04-18 16:01:18

Running command1 || command2 is the opposite, the second command will again be performed after the first one, but only if the first one fails (the exit state is larger than 0).
cd /tpm/ || echo oops
Screenshot from 2015-04-18 16:02:42

You can also combine these two
cd /tpm/ && echo yeah || echo oops
to get yeah instead of oops if you correct the typo. However, this can be tricky, it might look like an if-else-statement (if first command is successful do this else that) but it is not.

You will often find that people call the && an AND and || an OR operator, I am not really happy with that from a beginners perspective because all these chains mean perform command1 and then command2 no matter what operator you are using to combine them, the two last ones are just conditional. However, the background for calling them AND and OR is a different one and in that context the terms are right (based on what exit code the entire construct will return based on what the single commands will return) but it is not making them more beginner friendly. You will need that when you want to understand, why combining the operators to more complex structures is tricky. For beginners, they are closer to an if-statement that checks the success of the first command before it executes the second depending on that. And that will be enough to know for many use-cases.

Redirecting output using the |

In the first examples there wasn’t a real connection between the commands. Even with the && and || operators the command performed first didn’t need to have any connection to the second one, so whatever command fails or is successful triggers the next one, this changes with the pipe (|) operator. Usually, when you want to pass the output of one command to another, you would use a variable but the pipe is way easier, it redirects the output of one command to the input of the other. The basic usage of the pipe is like this
command1 | command2
this means that first command1 is performed and then command2 using the output of command1 as the input.

We have used that with the grep command a few times to filter the output of another command, however, the usage of a pipe is not restricted to grep you can use it with lots of commands. For example
date +%F | cowsay
makes a cow say the current date in ISO format.
Screenshot from 2015-04-17 18:45:26(cowsay is a joke program, you can install it using sudo apt-get install cowsay, date is used to display the current date and/or time)
For long directory listings it is sometimes useful to combine ls with the more command (the more command is often used to read files but it can display any text, there is also less and most, yeah, Linux people are funny, but more is better for screenshots)
ls -lA | more
Screenshot from 2015-04-17 21:29:57

For one of the following articles I planned to write about a few smaller commands that can be used in combination with a pipe to make them stronger. To give you an example of how complex a pipe can get look at this line

nl ~/.bash_history | sort -k 2  -k 1,1nr| uniq -f 1 | sort -n | cut -f 2 > /tmp/unduped_history

It is part of a script used to remove duplicate entries from bash_history (found here).

Writing to a file using > and >>

Writing the output of a command is in principle pretty similar to a pipe, just that the operator sends the output to a file instead of another command. It’s also a bit like chaining two commands. Funny enough, people sometimes say that writing to a file in the terminal is complicated. It really is not.

There are two operators to write output to a file > and >>. If you use
command > log.txt`
log.txt will only contain the output of that particular command, overwriting existing data. If you use
command >> log.txt
the data will be added to the end of the file. Example
cowsay "mooo" > test/mooo.txt
The command writes the outout of cowsay "mooo" to the file test/mooo.txt, we can read it using more test/mooo.txt
Screenshot from 2015-04-17 16:41:44

On a side note, if you invert the operator <, you can also read from a file but that is not necessarily a topic for beginners.

Grouping commands

At times it is necessary to group commands in some sort of subroutine, that can be done be enclosing them in curly brackets {}, the only thing you have to keep in mind is that you have to place a semicolon between the last command and the closing curly, like this
command1 && { command2 ; command 3;}
the second and the third command will be executed when the first command is successful, without the curlys the third command would always be executed because it does not depend on the previous code.

Tl;dr

The terminal (bash) offers you various ways to chain commands:

  • ; – simply executes one command after the other
  • && – executes the second command only if the first was successful
  • || – executes the second command only if the first was not successful
  • | – passes the output of the first command to the input of the second

You also have two ways to write to a file

  • > – overwrites existing data
  • >> – appends to existing data

To group commands you can use {}.

Using the Terminal – Part 3: the history and aliases

Using the Terminal – Part 3: the history and aliases

In the third part I will continue with some more basics. Now that you know a few commands you might want to know how to use them easier.

I promised to tell you a bit more about the history and how to use it more efficiently. The history is created by the shell, so it does not depend on the terminal application you are using. Next I will tell you a bit about aliases and how you can use them to make the terminal a little more your home. The aliases are also a function of the shell.

What is the history?

In fact, the history is just a text file stored in your home directory called .bash_history. Yes, it is that easy. A simple plain text file that you can open with your favorite text editor, you can even delete or change its entries. Each line represents a history entry.

How to control the history?

The history is controlled via the file .bashrc (it controls a lot of different shell features) and you can set various options to make the history more effective. It’s a simple text file so you can edit it with your favorite text editor, anyway, you should make a copy of the original file before starting to change it. Many options are already available, sometimes you just have to remove the hash (#) in front of the respective setting.

Changing HISTSIZE isn’t really necessary, for normal use the history is large enough.

The value HISTCONTROL is already set to ignoreboth, that is a combination of the values ignorespace and ignoredupes. ignorespace means that any command you type that begins with a space will be ignored. ignoredupes will stop the history from adding duplicate entries when when you enter the same command more than once in a row.

One thing you could do is to exclude certain commands, that is done by adding a line like this
HISTIGNORE="cd*:ls*:*--help:man*:clear"
to .bashrc. This would exclude all commands that start with cd, ls and man and all commands that end with --help as well as the command clear. Why? Cause they change nothing, so it’s not worth to remember them. You can also add you own aliases to the ignore list.

You can also add timestamps to your history entries by adding
HISTTIMEFORMAT=”%FT%T ”
to .bashrc, this would create an ISO8601-like timestamp (YYYY-MM-DDThh:mm:ss).
Screenshot from 2015-04-12 19:20:42

In fact you can do way more with your history than this but that is the part where it really starts to get complicated. Getting the behavior of the history to be exactly as you want it to be can be a bit of a pain in particular when you run multiple terminals.

Using the history

This is the by far most important part. There are multiple ways to use the history. One is the history command that just lists all the history entries, with a thousand entries that is a lot to scroll. You can also use the arrow keys (up and down) to browse the history, that is useful for recent commands but not for commands you used a few days ago.

One simple solution is to use history in combination with the grep or the egrep command. grep is a search command and you can filter the output of history with grep using a so called pipe with the the output of the former being used as the input of the latter. The egrep command is a bit more powerful. That sounds more complicated than it is:
history | egrep [searchterm]
So searching for all commands that contain zip use
history | egrep zip
This is particularly helpful in the beginning cause often remember a command you used vaguely.

Each entry has a number (n), you can use that for example to perform the exact same command again typing !n, you can even expand that line. That is really useful when you forgot to sudo a command, for the last history entry this is even easier, cause you can use !! to execute it again, so you just have to type sudo !!.
Screenshot from 2015-04-08 13:43:28
If you do not feel comfortable with the command being executed instantly you can add
shopt -s histverify
to .bashrc so the command will expend so you can check it before you execute it.

Another great method to search the history is the built-in search function (reverse-i-search) that you can open by pressing CTRL+R. It’s a typeahead search, so you just have to start entering the term you remember. To jump to earlier commands you have to press CTRL+R again. It is also possible to jump back to later commands using CTRL+S (called i-search) but that is by default not working, you can enable it by adding stty -ixon to .bashrc and switch off another feature or bind it to another key using bind '"\C-f": forward-search-history' for bind it to CTRL+F (it is usually used to do the same as the arrow-left key and therefor redundant).
Screenshot from 2015-04-12 18:47:44

What is an alias?

An alias can do lot’s of different things but but they all have in common they are meant to make things easier and adjust to your liking. You can for example use an alias for your favorite way to call a command. But you can also hide larger code snippets behind an alias like the alert command mentioned in an earlier post.

Per default the *buntus already have some aliases pre-configured, you can list them by typing alias. You will see that ls as used in the *buntus is already an alias for ‘ls –color=auto’. The syntax to define an alias is pretty simple to make .. an alias for cd .. you can use the command alias ..='cd ..' directly in your terminal (try it) but this will only last until you close the terminal. To make it permanent you can add the alias to .bashrc or (better) to a new file called .bash_aliases.

What can I use an alias for?

Virtually everything. You already saw a few example above that could be useful. I like to have two versions of ls as an alias
alias l='ls -lhp '
alias la='l -A '
I also have an alias for gvfs-trash
alias del='gvfs-trash'
Just make sure that you have an alias that is short and easy to type and to remember, del (for delete) is much easier to remember than gvfs-trash. You can also make an alias like this
alias hist='history | egrep '
to make searching the history easier, you just have to type hist and the term you want to search like hist zip to search all zip commands.

You can also use an alias to make commands that are potentially dangerous a little less dangerous by making the interactive, e.g. the rm command
alias rm=’rm -i’

Tl;dr

Two things that make the terminal much more effective also – but not only – for beginners are the history and the aliases. The history let’s you lookup commands you already used and let’s you even reuse and modify them. With aliases you can create custom commands for actions that you often use or that are hard to remember. Both are features of the shell, so you only have to do them once and they are available in every terminal application you use.

Do you have a favorite alias or a simple little history trick you like to share?

Using the Terminal – Part 2: shell, bash and some basic commands

Using the Terminal – Part 2: shell, bash and some basic commands

This one turned out be be longer than expected but I wanted to get to a point where you could actually do something with the stuff you read here.

In the first part I told you where you find the terminal, what different terminal applications are there as well as a couple of basics that many modern terminal applications share.

A short look under the hood

Before I go on, I want to go a bit more in depth, don’t worry, I won’t go too far. And even if you don’t understand this stuff, you should have at least read the terms once.

I told you in the first part, that all terminals speak the same language. That was not correct because in fact they are under the hood the same. The terminal application is just a way to pass commands to the actual shell, which is bash (that’s for Bourne Again SHell), when you enter a command into the terminal it will be interpreted by bash which than makes the computer do something. So what you actually get is the underlying shell and the terminal application itself and subsequently the features you get are a mixture of both and it is sometimes hard to figure out what belongs where, a lot of functions are already present in the shell that’s why they are shared by all the terminal applications. In one of the next parts I will tell you which files control these settings and how you can make use of them.

The Unix/Linux world knows different shells so terminal commands and features are not the same everywhere but usually in the Linux distributions you might use it is bash. The standard shell (called sh, which is a symlink to the actual shell) in the *buntus is dash (for Debian Almquist SHell, not to be confused with the application launcher of the Unity desktop of the same name). dash is faster but not very user-friendly, so terminals still use bash. You can read more about this in the Ubuntu Wiki
https://wiki.ubuntu.com/DashAsBinSh

This should be enough for this part, I know it is heavy stuff. You can forget everything now but bash and that when people talk about the terminal they often mean the shell. However, there is nothing wrong with saying terminal people will understand you, if not they just want to be a smart-ass ;). And we have to keep in mind that you are a home user and not an IT professional[tm].

Understanding your files and folders a bit

Before we can start with commands, I want – and have to – tell you a little about your file system, the folders, files and their names and how you can deal with them. Also here I don’t want to go too much in depth and keep it on the phenomenon level. There is certainly more you need to know in the long run but these where the first things that I found to be odd or cool or remarkable when I switched to Ubuntu.

Some differences between Windows and Linux

One major difference between Linux and Windows is, that for Linux temp and TEMP are two different folders while on Windows they are the same. Windows doesn’t care about capital letters, Linux does. Also text.txt and text.TXT are two different files.

On Linux you don’t have different drives even though you have them in your Windows system on the same box, there is no c:\ and d:\ on Linux there is just the root directory / (note that the slash has the opposite direction in Linux) and every drive is part of the root directory. Depending on the kind of drive, you find them either in /mnt/ or in /media/, the first being for example harddrives, the latter removeable drives like USB sticks or DVDs.

In Linux you can use virtually every character in a file or folder name. Only the / is reserved, while others are not liked when it comes to commands and you have to escape them with a backslash like the blank/space or you have to write the file or path in quotes. While this is really cool when it comes to Linux file systems, you might get a problem, when you want to copy such files to a Windows file system or store them on an NTFS/FAT drive, so better avoid characters that Windows doesn’t like. You find more on that topic in Wikipedia
http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
It’s a nice overview, that I can’t integrate here in such depth.

Special directory entries

Each directory has two special entries . (one period) and .. (two periods), the first is a link to itself, the latter a link to the parent directory, so if you are in /tmp/, . is /tmp/ itself and .. is /. The . is pretty handy, when you want to run a script, when you are in a directory that contains script.sh, you cannot just type script.sh to run it, you have to type ./script.sh. Usually, these entries are hidden, your file manager will for exmple most likely not show them cause for graphical interfaces they are of limited use.

Wildcards

In the terminal you can also use wildcards such as the asterisk (*) or the question mark (?). You might already know them from Windows cause they are used fairly often. The ? is exactly one character, the * any amount of characters including none.

These two already help you a lot. *.*~ for example matches all backup files, *.jpg all jpg files. But that already leads to a problem, because jpg doesn’t match JPG, but the terminal is pretty smart cause you can do some sort of simple regular expressions. To get all jpg files, no matter how they are written, you can do something like this *.[jJ][pP]*[gG]. Why the asterisk? Because some people use to write jpeg instead of jpg.

There is way more and there are also certain commands that can use the full power of real regular expressions. But I will keep it like this for now, this topic would deserve a tutorial on its own, I just need some of these things later.

Some useful commands

With the first set of commands I want to enable you to use the terminal as a basic file manager: browsing the directories, deleting, copying, renaming and moving files, creating and deleting directories.

cd

That is Change Directory (same as on Windows) and it is used to change the current directory to another and navigate through the file system. Most of the aforementioned stuff is important for cd, if you understood a bit of the file system, you understand the cd command.

You can jump into the home directory using cd ~ or by just cd, cd / jumps to the systems root directory and cd .. jumps one level up in the directory tree to the parent directory. The terminal can also autocomplete by hitting TAB or suggest by hitting tab twice. Instead of jumping from directory to directory you can also add an absolute or relative path (auto completion works there too), so it is no problem to jump from your home directory, directly to /usr/share/applications/ which you could also write it as ../../usr/share/applications/, this is the same path just relative using the parent directory twice. That doesn’t make sense in this case but sometimes such things are really handy when you start some scripting.
Screenshot from 2015-04-05 20:41:44

ls

ls is the command to LiSt the content inside a directory. The default output of ls is very compact. The most useful switch for ls in this regard is -lh (l for long and h for human readable), that creates an output that looks like the details output in your file manager with file sizes that you can actually read.
Screenshot from 2015-04-05 20:35:55

When a folder or file is written with a period in the beginning it is treated as a hidden folder or file in file managers, by default ls will not displaythem as . and .., you can display them using the -a switch. Files that have a trailing tilde are also hidden as backup files in file managers, however, the terminal will display backup files but you can hide them using -B

You can also filter the output of ls, to just display all the jpg files inside a directory you can use ls -lh *.[jJ][pP]*[gG]. Or you can display the content of directories you are not currently in, e.g., the subdirectories of your current directory using ls -lh *.

Here is a short list of some useful switches for ls that you can combine to something you can use to a nice output:

  • l – long form
  • h – human readable
  • a – all
  • A – all but .. and .
  • p – displays trailing slashes on folders
  • B – hides backup files
  • R – list subdirectories recursively

Besides ls the *buntu know a few aliases for ls with certain switches:

  • l for ls -CF
  • la for ls -A
  • ll for ls -alF

Also ls itself is on *buntu already an alias for ls --color=auto else you wouldn’t have colors in the output. I will tell you more about aliases and how you can make your own ones later (maybe in the next part).

From Windows you might know the command dir that exists in *buntu as well and it does the same as ls. In addition there is vdir which is ls -l.

sudo

The aforementioned commands do not change anything. When you want to change something you often need root access cause you can’t do much outside of your home directory without it.

You already know sudo from previous posts. Usually sudo isn’t used as a command by itself, it’s main use for you is to pass commands to root. But you could for example open a root shell using sudo -i as a command that is useful when you have to perform a lot of administrative tasks, you leave that session using exit.
Screenshot from 2015-04-05 20:49:36

You should never use sudo to perform tasks inside your home directory. You should also not run graphical applications using sudo, it is technically possible but not recommended, it is better to use gksudo or pkexec instead, while the latter is the recommended way and the former deprecated but at times still necessary.

What can happen is that files that actually belong to you get owned by root which means that you can neither change nor remove them. So, when using sudo be sure that you have to use sudo.

mkdir

mkdir is meant to MaKe DIRectories. It’s a very basic command that you find in lot’s of tutorials and install instructions. The basic usage is mkdir [directory] where [directory] can be both an absolute or relative path. There is just one pitfall, the parent directory for the directory you want to create must exist, if you want to create a complete path including the parent directories you have to use the switch -p.

cp

cp stand for CoPy. The usage is to copy a source to a target. To copy file.txt from your recent folder to into a subfolder called files you use cp file.txt files/, you can also copy multiple files cp file1.txt file2.txt files/ or use wildcards cp *.txt files/. cp comes with a bunch of options to create backups or synchronize between folders. For manual copying I suggest to use the -i switch, which makes the command interactive, usually it would not ask before it overwrites something.

mv

mv is used to MoVe files. It’s usage is pretty similar to cp the only difference is pretty obvious cp keeps the source, mv doesn’t, kinda self explanatory. If you move a file to a file with another name like mv file1.txt file2.txt you could also do some basic renaming, however, there are better ways to do that.

rm & gvfs-trash

rm is to ReMove or unlink or delete a file. This will not move the file to trash, it will unlink the file from the file system so it simply won’t be there anymore.

The basic usage a command like rm file.txt to remove file.txt. That is pretty easy but also not very powerful. Now let’s say you want to remove all backup files in a directory, that’s also pretty easy cause you can do this rm *.*~, which is a bit more powerful. On the interwebs you can find even more advanced oneliners to remove lot’s of files. that is even cooler but, please, don’t use them yet because as long as you don’t understand what you are doing you can delete a lot of stuff you didn’t want to delete, one false blank can make the difference. In case you do use such commands use at least the -i switch to make the command interactive.

Usually, rm would not delete directories, for directories you have to use th command rmdir but rmdir can’t delete directories that are not empty.To remove directories including their content, you can use rm with the -r switch.

There is a way on *buntu that makes life a bit less dangerous and that is moving files to trash using gvfs-trash. gvfs is for GNOME virtual file system, it’s usage is pretty similar to rm, but there is a way back. Most of the *buntus come with gvfs preinstalled, on others you can simply install the gvfs-bin or the trash-cli package.

Tl;dr

We have learned that under the hood of your terminal lies the shell which is bash. We have learned a bit about how to deal with files and folders, how to use wildcards. We have also learned some basic command like navigating through your directories, listing their content, creating new directories, copying, moving and removing files. That already allows you to understand a lot of things.

This was really a long one, hope it helps understand a bit. Use --help and man on the commands if you need to know more. there are many more things to discover.