Bash recursive file search. Find command: Powerful file search facility in Linux. Actions on files

Undoubtedly, when working with Linux, sometimes it becomes necessary file search with certain characteristics. These characteristics can be file size or type, permissions, and more.

Availability in Linux commands find, helps a lot to cope with file search according to various criteria.

Today we will analyze find files in Linux and give the main command options findthat you can apply in your work.

List of all files contained in the current directory and subdirectories

The main thing that you need to know is how to use this command, and is that the synopsis that you find with the “find person” command is not very quiet, because if that's what he says. Find where to look. This command is equivalent to entering any of the following.

Search for files in a specific path

Search for a file by name

Invert search criteria. Search only files or only directories. Search multiple directories. It is very useful to be able to search multiple directories or routes at the same time and only add them to parameters. Luis Armando Medina Follow me on Twitter.


Command format find:

findway-options

where way is the directory in which to search. The following values \u200b\u200bcan be specified as the path:

. - search in the current directory;

/ - search from the root directory;

~ - search in the home directory.

As for the options, there is a much larger list that it is imperative to read carefully (this will help a lot in the future!). So, basic find command options:

At first it will seem like the letter doesn't make much sense and you will never remember it. The command structure looks like this: find the expression path. The path is clear - this directory will look like below. Often used are, for example, type, owner. Another important option is the so-called action. This allows us to run any system command and pass it to a file as a parameter. Finally, we have operators for folding expressions.

We will focus on hands-on demonstrations. Accesses the disk for all directories called experiments. We must treat the record so that it is not interpreted by the shell. If we want to find a subdirectory in the current directory and don't go through recursively.

-name - search for files by name using the given template;

-user - search for files belonging to the specified user;

-group - search for files belonging to the specified group;

-perm - search for files with the specified access mode;

-type - search for files of a certain type. There are enough types too:

  • b - special block file;
  • d - directory;
  • c - special character file;
  • f is a regular file;
  • l - symbolic link;
  • p - named pipe;
  • s - socket.
-size n - search for files with size n units;

-mtime -n + n - search for files whose content changed less than (-) or more than (+) days ago.

Also interesting is the search by the number of files and sizes. This example finds everything in a home directory that has changed in the last seven days. Everything changed more than seven days ago. Finds all files in the current directory that were changed before the file.

The empty curly braces will be replaced with the path to the found file. The backslash before the semicolon is important. But the semicolon is the character that usually separates commands. The semicolon will be interpreted as a command separator when run. So we need to handle it with \\\\ or write it like ;. An example will be found in action. directory and subdirectories for all files and lists details. The previous example shows us the strength of the claim.

Consider some examples of using the command find :

The most commonly used option is -namewhich searches for files by name.

Examples with the -name option :

$ find / mnt / usb -name "* .mp3" -print

will search for all files (indicated by the * sign) with the extension .mp3 on a USB device mounted in the / mnt / usb directory.

$ find ~ -name "test *" -print

will display a list of home directory files starting with test.

If you need to find files starting with certain letters (for example, from a to j), then it will be convenient to use regular expressions here, which are extremely convenient to use:

$ find / -name "*" -print

The above command will find all files on the system starting with letters from a to j.

Search for files with specific access modes

If you need to find files with certain access modes, the option will help you -perm, which will easily help with this.

For example, let's search for files with access mode 775 (owner and group have full rights and other users have write restrictions) located in the current directory:

$ find. -perm 775 -print

Searching with find with the -perm option, you can use another way - you can put a hyphen in front of the mode value and then the search will be made for files for which all the specified permission bits are set. Moreover, the rest of the bits are ignored in this case.

For example, let's find files to which the users of the group have full access:

$ find. -perm -070 -print

Instead of a hyphen, you can specify a plus sign. In this case, a search will be made for files that have at least one of the specified permission bits set. The rest of the bits are ignored.

File search a specific user or groups

Finding files for a specific user is extremely simple to implement. To do this, just run the command:

$ find / -user admin -print

The above command will produce file search on the system owned by the user admin.

In order to find files belonging to a certain group (for example managers), run the command:

$ find / -group managers -print

To search for files of non-existent users or groups, you can use the options -nouser and -nogroup:

$ find / -nouser -print

$ find / -nogroup -print

Search for files of a specific type

One of the convenient features of the team find, is the ability to search for files of a specific type. Consider the use cases for the option -type:

Searching for symbolic links in the / etc directory:

$ find / etc -type l -print

Display a list of directories present in the / mnt / raid directory

$ find / mnt / raid -type d -print

Search for files of a specific size

Option -size allows you to search for files of a certain size and looks like this when executed:

$ find. -size 2000k -print

The above command will find and display on the screen the 2 megabyte files located in the current directory. If, for example, you need to find files less than 500 kilobytes in size, the command will look like this:

$ find. -size -500k -print

If you need to find files larger than 600 megabytes, then use the command:

$ find / -size + 600M -print

Finding files using the -mtime option

Option -mtime allows you to find files that have changed over a period of time.

For example, we are faced with the task of finding files located in the / mnt / raid / upload directory and changed over the last 5 days. The command will help us with this:

$ find / mnt / raid / upload -mtime -5 -print

If we need the opposite, for example, to find files that have not changed for a week, use the command:

$ find / mnt / raid / upload -7 -print

Command find is an extremely convenient tool for file search and can also be used for file search on NFS drives (network file systems), but in this case it is necessary to take into account that it will take much more time to search for something on NFS than on local disks.

In this article, we have covered only the basic options of the find command that will help you in your work. Use what is convenient and do not worry about trifles!

In a server environment, working with the command line is time consuming. The bash shell is often used - command shell the default for most distributions.

It is likely that during a terminal session, common commands will be repeated often, and variations of these commands will be even more frequent. Of course, typing each command manually at first is very useful, since it is an extra opportunity to practice, but at some point it becomes annoying and annoying.

Fortunately, the bash shell has some pretty well designed history features. Being able to use and manage history productively in bash allows you to spend less time typing commands, and thus increases the amount of work done. As you know, the so-called DRY principle (Don’t Repeat Yourself) is popular among developers. The productive use of history in bash helps you work with information according to this principle.

This tutorial demonstrates all the features on a VPS running Ubuntu 12.04, but almost all modern ones. linux distributions will work in a similar way.

History settings in bash

Before using history, you need to edit some bash settings to make it more usable.

Bash allows you to edit the number of previous commands to keep in history. To do this, bash has two separate options: the HISTFILESIZE parameter specifies the number of commands stored in the history file, and HISTSIZE specifies the number of commands that are stored in memory for the current session.

This means that you can set reasonable limits on the size of the history for the current session in memory, as well as store the larger history on disk for later use.

By default, bash sets these parameters very conservatively, so they need to be extended to be able to use a more complete history. Some distributions have already increased the default history parameter values.

To change these options, open the ~ / .bashrc file with an editor:

Find the options "HISTSIZE" and "HISTFILESIZE". If the values \u200b\u200bare set, change them. If there are no such parameters in this file, add them. This tutorial can get by with 10,000 lines for disk and 5,000 lines stored in memory. These are modest values \u200b\u200bfor most systems, but even they will have to be lowered if they affect performance:

HISTSIZE \u003d 5000
HISTFILESIZE \u003d 10000

By default, bash writes history at the end of each session, overwriting and updating an existing file. This means that when working in multiple bash sessions, only the history of the last completed session will be saved.

This can be worked around by setting the "histappend" option, which will add history rather than overwrite it. It may already be installed; otherwise, it can be activated by adding the following line:

shopt -s histappend

In order for bash to add commands to history immediately, without waiting for the end of the session (so that the commands of one terminal are immediately available in another), you can set or add the command "history -a" for the option "PROMPT_COMMAND", which contains commands that are executed before each new command line.

But such a team needs a trick to work properly. Add “history –a” to the history file, then clear the current history of this session using “history –c”, then read the edited history file and return to the history of this session using “history –r”.

It looks something like this:

export PROMPT_COMMAND \u003d "history -a; history -c; history -r; $ PROMPT_COMMAND"

When finished, save your changes and close the file.

Log out and back in to activate the changes, or use the source command on this fileby typing:

source ~ / .bashrc

View previous history inBash

To view history in Bash, use the "history" command. It prints out the previous commands, per command per line. In most cases it should print the number of lines set by the HISTSIZE value. There are not so many commands at the moment:

history
. . .
43 man bash
44 man fc
45 man bash
46 fc -l -10
47 history
48 ls -a
49 vim .bash_history
50 history
51 man history
52 history 10
53 history

It also displays the ordinal number of the command. Each command is associated with a number for ease of use.

The output can be shortened by specifying the number of commands after "history". For example, if you want to display only the last 5 entered commands, we can type:

history 5
50 history
51 man history
52 history 10
53 history
54 history 5

To find all commands in history that contain a specific line, you can simply use grep after the pipe character. For example, to find lines containing "cd", type:

history | grep cd
33 cd Pictures /
37 cd ..
39 cd Desktop /
61 cd / usr / bin /
68 cd
83 cd / etc /
86 cd resolvconf /
90 cd resolv.conf.d /

Running Commands from History in Bash

Learning how to output commands, of course, is useful, but, apart from using the ordinal number of commands, it gives almost nothing. To call any previous command, you must use a special syntax.

You can call any of the previous commands by entering its number and placing an exclamation mark "!" In front of it. Building on the example history above, you can quickly display the online manual page simply by typing:

This will immediately call and execute command in history number 51.

You can also execute commands relative to the current position. This is done using the syntax "! -N", where "n" must be replaced with the number of the command to be executed.

For example, if you need to display and execute the penultimate typed command, you can type "! -2". So, if the contents of the long path to the directory were displayed, and then the echo command was entered, and now you need to display the path again, then the session may look like this:

ls / usr / share / doc / manpages
echo hello
! -2 # lists the contents again

To re-execute the last command, instead of using "! -1" in bash, you can use the "!!" hot command, which does:

Many people use this in case they have typed a command that requires sudo privileges. When typing "sudo !!" the command will be rerun with sudo privileges. Such a session looks something like this:

touch / etc / hello
touch: cannot touch `/ etc / hello": Permission denied
sudo !!
sudo touch / etc / hello
password for demouser:

This example demonstrates another property of this useful syntax. In fact, this is a simple replacement, so you can include it in other commands if necessary.

Scrolling through history in Bash

There are several ways to scroll through history in Bash, displaying each subsequent command on the command line for editing.

The most common way is to press the up arrow key on the command line.

Each additional press of this key will step backward in the command line history. To change direction, use the down arrow key, which scrolls through history up to the last command line.

Instead of using the arrow keys, you can use the keyboard shortcuts: "CTRL-p" to scroll back through history, and "CTRL-n" to scroll forward.

You can use "Meta-\u003e" to return to the current command line. In most cases, "meta" and the "\u003e" character replace the combination "ALT-Shift-.". This is very useful in case the current command line is far enough away.

To move to the first line of history, use the reverse maneuver, “Meta-<». Обычно это сочетание замещает «ALT-Shift-,».

As a summary, below is a list of the most important history navigation keys:

  • Up arrow key: scroll back through history;
  • CTRLp: scroll back through history;
  • Down arrow key: scroll forward through history;
  • CTRLn: scroll forward through history;
  • ALTShift-. : move to the end of history (to the last command entered);
  • ALTShift-, : move to the beginning of the history (to the first command entered).

Search history inBash

Although using the combination "history | grep "is the easiest way to perform some procedures, its work in many situations is far from ideal.
Bash has history search functionality. For example, it is often used to search the history in the opposite direction (the most recent results are displayed first) using the keyboard shortcut "Ctrl-r".

For example, you can type "Ctrl-r" and type part of the previous command. You only need to type part of the team. If the value entered matches an unnecessary command, you can press Ctrl-r again to display the next result.

If the required command was accidentally skipped, you can change the search direction using the combination "CTRL-s". It is also useful when navigating through the history described in the previous chapter to search forward.

Note: in many terminals, the combination "CTRL-s" blocks the terminal session. That is, when you try to use it for searching, it will "freeze" the terminal. To unlock the session, simply type "Ctrl-q".

These pause and resume functions are unnecessary in most modern terminals, so you can disable them by typing:

Now you need to add this to the "~ / .bashrc" file to ensure that the command is always executed.

This search combination will now work correctly.

Search for the entered part of the command

A common way to search is to type in part of a command, find out if it has been completed before, and then find it in history.

What is the correct way to perform a search using the data already entered on the command line? Move the cursor to the beginning of the line with CTRL-a, then reverse the history with CTRL-r, insert the current line into the search with CTRL-y, and use CTRL-r again to search back.

For example, you need to update the package cache in Ubuntu. This command has already been executed, but to check if this is the case, you can type sudo:

At this stage, you can see that this command has definitely been executed recently. Now press:

This will move the cursor to the beginning of the line.

This will invoke a reverse sequential search through history. This action has the side effect of copying all the contents of the command line after the current cursor position and pasting it to the clipboard.

This pastes the parts of the command just copied from the command line into the search.

Now you need to run the reverse history search again to find the commands containing the specified part.

This procedure seems rather confusing at first, but it just takes some getting used to. It is extremely useful when half of the complex commands have been entered and now requires a story to complete.

In addition, all these actions can be combined into one:

Advanced use of history in bash

Having looked at the basic techniques for using history in bash. Among them:

  • !! : display the last command;
  • ! n: go to the command with the sequence number "n";
  • !- n: go to the command that was numbered before the last command.

Event identifiers

The above three combinations are called identifiers of the event... Basically, it is a way of invoking previous commands from history using certain criteria.

For example, to run the last "ssh" command, you can use:

This action looks for lines that start with "ssh". To find a sequence that is not at the beginning of a command, you can enter the "?" before and after the sequence. For example, to repeat the last "apt-cache search" command, you would type:

You can also use variations of the output of the last command ("!!"). Perform a quick find and replace by typing:

^ original ^ replacement ^

This will call the last command (like "!!"), look for a match with the value "original", and replace it with the value "replacement". Then the command will be executed.

It is very convenient to use when you need to correct spelling errors. For instance:

cat / etc / hosst
cat: / etc / hosst: No such file or directory
^ hosst ^ hosts ^

Determinants of words

You can add a colon (:) after the event qualifiers and then add determinant of a wordto select part of the matched command.

It works by dividing the command into "words" - spaces separated by spaces. This opens up new possibilities for interacting with command parameters.

The command itself is numbered zero, the first argument is 1, and so on.

For example, you can display the contents of a directory and then change it like this:

ls / usr / share / doc / manpages
cd !!: 1

If this operation is performed with the last running command, then this combination can be compressed by removing the second "!" and colon:

It will work the same way.

The first argument can be referenced with a ^, and the last argument with $. These characters are much more useful when working with ranges rather than sequence numbers. For example, there are three ways to extract all the arguments from the previous command to the new one:

!!:1*
!!:1-$
!!:*

The asterisk "*" is used to indicate any output other than the original command. Similarly, you can use the word number followed by * to indicate that everything after the specified word must also be included.

Modifiers

The last thing you can add to the behavior of the called history line is to change the behavior of the call to control the text itself. Modifiers are added after the additional ":" character at the end of the line.

For example, you can shorten the path to a file using the "h" modifier (which means "head"), which removes the path to the last slash character (/). Remember: this will not work as expected if you need to shorten the directory path that ends with a slash.

This is often used when modifying a file and needing to navigate to its directory to perform operations on its associated files.

cat / usr / share / doc / manpages / copyright

After that, you need to go to the directory. This can be done with the command "cd" on the parameter string, "cutting off" the filename at the end.

cd !!: $: h
pwd
/ usr / share / doc / manpages

Alternatively, you can reverse the procedure by shortening the path and using only the filename using the "t" modifier (which means "tail"). For example, you can search for the last "cat" command using the "t" flag to leave only the filename.

You can also just leave the full path and the command will work as expected. But sometimes it doesn't. For example, if, when working with a file nested in several subdirectories of the current directory, you use a relative path, and change the subdirectory using the "h" modifier, then you will no longer be able to use the relative path to this file.

Another very useful modifier is "r", which removes the tail suffix like ".xxx". This is useful when using the "tar" command to extract a file and need to change to a directory afterwards. Assuming the directory name is the same as the file name, you can do something like:

tar xzvf long-project-name.tgz
cd !!: $: r

If the tarball uses the tar.gz extension instead of tgz, just enter the modifier twice:

tar xzvf long-project-name.tar.gz
cd !!: $: r: r

A similar modifier, "e", removes everything except the tail extension.

If you just need to find the command you are calling and not execute, you can use the "p" modifier to have bash display the command again.

This is useful if you want to make sure that you have chosen the correct portion of the story. In addition, this modifier will place the selected command in the history in case it needs further editing.

For example, the "find" command was previously run on the home directory, but now it needs to be run from that directory (/). You can check whether the substitution was performed correctly as follows (provided that this command has # 119):

find ~ -name "file1" # original command
! 119: 0: p /! 119: 2 *: p
find / -name "file1"

If the command was printed correctly, you can run it with:

There is also an easier way to perform substitution in commands: for this you can use the syntax s / original / new /

For example, the action described above can be performed like this:

This will replace the first instance of the search pattern. To substitute for each match, use the "g" and "s" modifiers. For example, to create files named "file1", "file2" and "file3" and directories "dir1", "dir2", "dir3", you would use:

touch file1 file2 file3
mkdir !!: *: gs / file / dir /

Outcome

This guide helps you master the basic concepts of using history. Of course, some of the described functions will be useful in rare cases, but it is also necessary to know about them and be able to use them.

In general, all the described possibilities of using history can significantly speed up the work.

Tags:,