You're missing a lot by escaping the command line

~ 3 min

If you are one of those people who have migrated from Windows to Linux but you are still using a graphical user interface like Gnome or KDE to do daily routine tasks, you are missing a lot.


I'm not saying you shouldn't use a graphical user interface. I'm saying if you are using the GUI to escape doing things in command line, you're really doing it wrong.

What are you talking about? You might say. What am I missing? A lot, actually. But I hate typing, you might say. Get used to it, get out of your comfort zone. Why crawl when you can sprint? How? Read on.

Let's say you are asked to replace a set of words in a bunch of files. You open a file editor like gedit or kate. You open one of the files and do a Ctrl+F or Ctrl+H to find the word you have to replace. After a few minutes (depending on how big the file is) you are done with the file and open the next one. You do the same with the next file and go on to edit the next. At this rate, you are going to be done in a couple of hours.

If you were a little smart, like you're going to be in a few minutes, you'd probably put all your files in a directory and open the directory in a more advanced text editor like "Sublime Text", click on the directory name and choose "Replace in All Files". You enter the text you want to find and the one you want to replace it with and hit "Replace All". That's fast and you didn't use the command line for it. So why bother?

There's a way to do all this in just a few seconds. Just a few commands. You only have to learn a few commands. The command you need to use is called sed. Let's say you are a database guy and you have exported a bunch of data from your production database and you want to import it into your dev database. You want to replace anything that starts with PROD_ with TEST_. All you need to do is run:

sed -i 's/PROD_/TEST_/' file.sql

That's it. Seriously. It's going to be so fast that you will not believe anything was done at all. But go on and open the files to check the result. There's a tiny little catch though. This works on a single file at a time. But this shouldn't discourage you from the command line. There's a simple remedy. If your files have a common part like if they all have the extension .sql then you can specify the target file like the glob pattern *.sql. The edited command will look like this:

sed -i 's/PROD_/TEST_/' *.sql

If the file names are different though or if you don't know what files might contain the word you are looking for, there's a simple solution for that too. You can find all the files that contain your word using the grep command:

grep -rl PROD_ .

The parameter r means to recursively go through directories and l means to only show file names. By default grep will also show you the line that contains the text you are looking for which might be too long but it could also be useful. The . (dot) means to start from the current directory.

Now that you have the file names, how can you use them to replace the text? We use a tiny bit of bash programming:

for i in $(grep -rl PROD_ .); do sed -i 's/PROD_/TEST_/' $i; done;

Here's what's going on here. We know we can get the file names we want using grep. We use a for loop to go through the file names. The $() let's us give the output of our command to the for loop. The syntax for a for loop is:

for i in list; do
  # your logic here;
done;

We just used our grep command in place of the list and put our logic inside the body of the for loop. For the record, since each statement in bash is ended with a semicolon, we can put everything in a single line. Also, inside the body of the loop, we can access the current item using $i.