A Few Handy Linux Commands (Part 2)

Chukwudike
GitStacks

--

This is a sequel to the first article I wrote on some useful commands in Linux, I will be sharing some more commands I use rather often when working on a Linux OS.

grep Command

grep is one of the most useful and powerful commands in Linux for text processing. grep searches one or more input files for lines that match a regular expression and writes each matching line to standard output.

A regular expression or regex is a pattern that matches a set of strings. A pattern consists of operators, constructs literal characters, and meta-characters, which have special meaning.

Literal Matches

The most basic usage of the grep command is to search for a literal character or series of characters in a file. For example, to display all the lines containing the string “bash” in the /etc/passwdfile you would run the following command:

grep bash /etc/passwd

The output should look something like this:

root:x:0:0:root:/root:/bin/bash
bryan:1000:1000:bryan:/home/bryan:/bin/bash

In this example, the string “bash” is a basic regular expression that consists of four literal characters. This tells grep to search for a string that has a “b” immediately followed by “a”, “s”, and “h”.

By default, the grep command is case-sensitive. This means that the uppercase and lowercase characters are treated as distinct.

To ignore case when searching, use the -i option (or --ignore-case).

It is important to note that grep looks for the search pattern as a string, not a word. So if you were searching for “gnu”, grep will also print the lines where “gnu” is embedded in larger words, such as “Cygnus” or “magnum”.

If the search string includes spaces, you need to enclose it in single or double quotation marks:

grep "Gnome Display Manager" /etc/passwd

There’s a lot to learn when working with grep and regex and I am basically scheming the surface, you can learn more here

find Command

The find command is one of the most powerful tools in the Linux system administrators' arsenal. It searches for files and directories in a directory hierarchy based on a user-given expression and can perform user-specified action on each matched file.

find Command Syntax

The general syntax for the find command is as follows:

find [options] [path...] [expression]
  • The options attribute controls the treatment of the symbolic links, debugging options, and optimization method.
  • The path... attribute defines the starting directory or directories where find will search the files.
  • The expression attribute is made up of options, search patterns, and actions separated by operators.

Find Files by Name

Finding files by name is probably the most common use of the find command. To find a file by its name, use the -name option followed by the name of the file you are searching for.

For example, to search for a file named document.pdf in the /home/bryan directory, you would use the following command:

find /home/bryan -type f -name document.pdf

To run a case-insensitive search, change the -name option with -iname:

find /home/bryan -type f -iname document.pdf

The command above will match “Document.pdf”, “DOCUMENT.pdf” ..etc.

Find Files by Extension

Searching for files by extension is the same as searching for files by name. For example, to find all files ending with .log.gz inside the /var/log/nginx directory, you would type:

find /var/log/nginx -type f -name '*.log.gz'

It is important to mention that you must either quote the pattern or escape the asterisk * symbol with a backslash \ so that it doesn’t get interpreted by the shell when you use the wildcard character.

To find all files that don’t match the regex *.log.gz you can use the -not option. For example, to find all files that don’t end in *.log.gz you would use:

find /var/log/nginx -type f -not -name '*.log.gz'

Find Files by Type

Sometimes you might need to search for specific file types such as regular files, directories, or symlinks. In Linux, everything is a file.

To search for files based on their type, use the -type option and one of the following descriptors to specify the file type:

  • f: a regular file
  • d: directory
  • l: symbolic link
  • c: character devices
  • b: block devices
  • p: named pipe (FIFO)
  • s: socket

For instance, to find all directories in the current working directory you would use:

find . -type d

Find and Delete Files

To delete all matching files, append the -delete option to the end of the match expression.

Ensure you are using this option only when you are confident that the result matches the files you want to delete. It is always a good idea to print the matched files before using the -delete option.

For example, to delete all files ending with .temp from the /var/log/, you would use:

find /var/log/ -name `*.temp` -delete

Use the -delete option with extreme caution. The find command is evaluated as an expression and if you add the -delete option first, the command will delete everything below the starting points you specified.

Find and Replace String with sed

When working with text files, you’ll often need to find and replace strings of text in one or more files.

sed is a stream editor. It can perform basic text manipulation on files and input streams such as pipelines. With sed, you can search, find and replace, insert, and delete words and lines. It supports basic and extended regular expressions that allow you to match complex patterns.

The general form of searching and replacing text using sed takes the following form:

sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
  • -i - By default, sed writes its output to the standard output. This option tells sed to edit files in place. If an extension is supplied (ex -i.bak), a backup of the original file is created.
  • s - The substitute command, probably the most used command in sed.
  • / / / - Delimiter character. It can be any character but usually the slash (/) character is used.
  • SEARCH_REGEX - Normal string or a regular expression to search for.
  • REPLACEMENT - The replacement string.
  • g - Global replacement flag. By default, sed reads the file line by line and changes only the first occurrence of the SEARCH_REGEX on a line. When the replacement flag is provided, all occurrences are replaced.
  • INPUTFILE - The name of the file on which you want to run the command.

For demonstration purposes, we will be using the following file:

                   file.txt
123 Foo foo foo
foo /bin/bash Ubuntu foobar 456

If the g flag is omitted, only the first instance of the search string in each line is replaced:

sed -i 's/foo/linux/' file.txtOutput123 Foo linux foo 
linux /bin/bash Ubuntu foobar

With the global replacement flag sed replaces all occurrences of the search pattern:

sed -i 's/foo/linux/g' file.txtOutput123 Foo linux linux
linux /bin/bash Ubuntu linuxbar

As you might have noticed, the substring foo inside the foobar string is also replaced in the previous example. If this is not the wanted behavior, use the word-boundary expression (\b) at both ends of the search string. This ensures the partial words are not matched.

sed -i 's/\bfoo\b/linux/g' file.txtOutput123 Foo linux linux
linux /bin/bash Ubuntu foobar

To make the pattern match case insensitive, use the I flag. In the example below, we are using both the g and I flags:

sed -i 's/foo/linux/gI' file.txtOutput123 linux linux linux 
linux /bin/bash Ubuntu linuxbar

Pipe (|) Command

This “pipe” command is readily available on UNIX/Linux platforms. This command pipes the output of the previous command to the next command. There are literally TONS of situations where this method offers serious value.

Before jumping deeper, there’s something to know of. Every single program in the UNIX/Linux system has 3 built-in data streams.

  • STDIN (0) — Standard input
  • STDOUT (1) — Standard output
  • STDERR (2) — Standard error

When we’re going to work with “pipe” tricks, “pipe” will take the STDOUT of a command and pass it to the STDIN of the next command.

A good example that explains this command is below

ls | grep ".txt"

This lists all the files and highlights all the files that have the “.txt”, we’ve basically just piped the output of the ls command as the input of the grep command.

We can use multiple pipes as needed. Let’s say we want to count the number of files that have the “.txt” extension.

ls | grep ".txt" | wc -l  (wc -l : it counts the number of lines of input)

Xargs Command

The xargs utility allows you to build and execute commands from standard input. It is usually used in combination with other commands through piping.

With xargs, you can provide standard input as an argument to command-line utilities like mkdir ,rm , sed etc.

How to Use Linux xargs Command

xargs reads arguments from the standard input, separated by blank spaces or newlines, and executes the specified command using the input as command’s arguments.

The syntax for the xargs command is as follows:

xargs [OPTIONS] [COMMAND [initial-arguments]]

The most basic example of using xargs would be to pass several strings separated with whitespace using a pipe to xargs and run a command that will use those strings as arguments.

echo "file1 file2 file3" | xargs touch

In the example above, we are piping the standard input to xargs, and the touch command is run for each argument, creating three files. This is the same as if you would run:

touch file1 file2 file3

How to View the Command and Prompt the User

To print the command on the terminal before executing it use the -t (--verbose) option:

echo  "file1 file2 file3" | xargs -t touchtouch file1 file2 file3

Using xargs with find

xargs is most often used in combination with the find command. You can use find to search for specific files and then use xargs to perform operations on those files.

To avoid issues with file names that contain newlines or other special characters, always use the find -print0 option, which causes find to prints the full file name followed by a null character. This output can be correctly interpreted by xargs using the -0, (--null) option.

In the following example, find will print the full names of all files inside the /var/www/.cache directory and xargs will pass the file paths to the rm command:

find /var/www/.cache -type f -print0 | xargs -0 rm -f

The following command will recursively search for files in the current working directory and pass the file names to sed.

find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

Using Multiple Commands

Sometimes to save time you might want to run multiple commands together here are few ways to go that below

To run commands sequentially in one line use (;)

ls ; pwd ; whoami

To run commands in parallel in other words concurrently use the (&) operator

touch me.txt & touch us.txt

To run commands such that the previous command has to be successful before the next command, use the (&&) operator. If the first command fails the next command will not run.

cd /home/docs && cat linux.txt

To run either of two commands depending on the success or failure of the first command use the (||) operator

cd /home/docs || mkdir -p /home/docs

Aliases

Do you often find yourself typing a long command on the command line or searching the bash history for a previously typed command? If your answer to any of those questions is yes, then you will find bash aliases handy. Bash aliases allow you to set a memorable shortcut command for a longer command.

Bash aliases are essentially shortcuts that can save you from having to remember long commands and eliminate a great deal of typing when you are working on the command line.

Creating Bash Aliases

Creating aliases in bash is very straight forward. The syntax is as follows:

alias alias_name="command_to_run"

An alias declaration starts with the alias keyword followed by the alias name, an equal sign, and the command you want to run when you type the alias. The command needs to be enclosed in quotes and with no spacing around the equal sign. Each alias needs to be declared on a new line.

The ls command is probably one of the most used commands on the Linux command line. I usually use this command with the -la switch to list out all files and directories, including the hidden ones in long list format.

Let’s create a simple bash alias named ll which will be a shortcut for the ls -la command. To do so type open a terminal window and type:

alias ll="ls -la"

Now, if you type ll in your terminal, you’ll get the same output as you would by typing ls -la.

The ll alias will be available only in the current shell session. If you exit the session or open a new session from another terminal, the alias will not be available.

To make the alias persistent you need to declare it in the ~/.bash_profile or ~/.bashrc file.

Open the file in your vi editor or any text editor :

vi ~/.bashrc

and add your aliases:

~/.bashrc

# Aliases
# alias alias_name="command_to_run"
# Long format list
alias ll="ls -la"
# Print my public IP
alias myip='curl ipinfo.io/ip'

The aliases should be named in a way that is easy to remember. It is also recommended to add a comment for future reference.

Once done, save and close the file. Make the aliases available in your current session by typing:

source ~/.bashrc

As you can see, creating simple bash aliases is quick and very easy.

History

If you spend a lot of time on the command line, viewing the history of the commands you have previously run could be a useful feature that can make your day-to-day work easier and improve your productivity.

history is a shell builtin, and its behavior may slightly differ from shell to shell. We will cover the Bash builtin version of history.

In its simplest form, when invoked without any option or argument, the history command displays the whole history list with line numbers.

history...
467 git push
468 tail -f var/logs/error
469 nano +22,5 functions.sh
470 source project-env/bin/activate
471 history

Typing !n executes the n-th command from the history list, and !-n the command n lines back. In the following example, we’re executing the command on line 467:

!467

Another way to execute a command is to use !word expansion. word refers to the most recent command starting with ‘word’.

Typically, history displays many lines of output that don’t fit on the screen. To view the output one page at a time, pipe it to a pager program like more or less command:

history | less

To display the last n lines, pass the number as an argument to the command. For example, to view only the last five lines from the history list you would type:

history -5

Use the up and down arrow keys to navigate the entries in the list. When the command you’ve searched for is shown press Enter to execute it.

Type !! to execute the previous command:

!!

This is especially usefully when you forget to perpend a command with sudo , and instead of re-typing the command you can type:

sudo !!

!-1 is the same as !! and executes the last command from the history list, !-2 second to last, and so on.

These are about my most used command in Linux, obviously, these are not the only command on the Linux OS and there so are much more, however, these are very useful ones and this series is probably one to bookmark for references.

There are so many Commands to learn however, please don’t get overwhelmed to know all of them. I remember when I was starting out in Linux, I wanted to know and master all the commands ahahahah. I soon found out that was a herculean task that wasn’t really necessary. What you need to master is the basic commands and then learn how to read the docs when you want to perform a task you don’t know the command for and you will be just fine. I find this resource immensely helpful.

I hope you learned something new from this article, please leave some claps and a comment. Thanks for reading!

--

--