Linux first file in directory

Find file in directory from command line

In editors/ides such as eclipse and textmate, there are shortcuts to quickly find a particular file in a project directory. Is there a similar tool to do full path completion on filenames within a directory (recursively), in bash or other shell? I have projects with alot of directories, and deep ones at that (sigh, java). Hitting tab in the shell only cycles thru files in the immediate directory, thats not enough =/

8 Answers 8

find /root/directory/to/search -name 'filename.*' # Directory is optional (defaults to cwd) 

Standard UNIX globbing is supported. See man find for more information.

If you’re using Vim, you can use:

Or :tabn or any Vim command which accepts a filename.

@Bryan Oakley, Thanks for the edit, but it overwrote my addition about Vim! I reworded the directory argument in my answer. Thanks.

Here’s an attempt at making an alias out of it for searching current directory alias ff=»find . -name » . Usage: ff Rand* ff exactname.c , etc.

If you’re looking to do something with a list of files, you can use find combined with the bash $() construct (better than backticks since it’s allowed to nest).

for example, say you’re at the top level of your project directory and you want a list of all C files starting with «btree». The command:

will return a list of them. But this doesn’t really help with doing something with them.

So, let’s further assume you want to search all those file for the string «ERROR» or edit them all. You can execute one of:

grep ERROR $(find . -type f -name 'btree*.c') vi $(find . -type f -name 'btree*.c') 

I use ls -R, piped to grep like this:

where -R means recursively list all the files, and -i means case-insensitive. Finally, the patter could be something like this: «std*.h» or «^io» (anything that starts with «io» in the file name)

When I was in the UNIX world (using tcsh (sigh. )), I used to have all sorts of «find» aliases/scripts setup for searching for files. I think the default «find» syntax is a little clunky, so I used to have aliases/scripts to pipe «find . -print» into grep, which allows you to use regular expressions for searching:

# finds all .java files starting in current directory find . -print | grep '\.java' #finds all .java files whose name contains "Message" find . -print | grep '.*Message.*\.java' 

Of course, the above examples can be done with plain-old find, but if you have a more specific search, grep can help quite a bit. This works pretty well, unless «find . -print» has too many directories to recurse through. then it gets pretty slow. (for example, you wouldn’t want to do this starting in root «/»)

Читайте также:  Modbus tcp client linux

I use this script to quickly find files across directories in a project. I have found it works great and takes advantage of Vim’s autocomplete by opening up and closing an new buffer for the search. It also smartly completes as much as possible for you so you can usually just type a character or two and open the file across any directory in your project. I started using it specifically because of a Java project and it has saved me a lot of time. You just build the cache once when you start your editing session by typing :FC (directory names). You can also just use . to get the current directory and all subdirectories. After that you just type :FF (or FS to open up a new split) and it will open up a new buffer to select the file you want. After you select the file the temp buffer closes and you are inside the requested file and can start editing. In addition, here is another link on Stack Overflow that may help.

The linux/unix «find» command.

Источник

Getting the first file in a directory in bash

How do you get the first file in a directory in bash? First being the what the shell glob finds first. My search for getting the first file in a directory in bash brought me to an old post with a very specific request. I’d like to document my solution to the general question for posterity and make a place for people to put alternative solutions they’d like to share.

By «file», do you mean «regular file», or are you also interested in directories, symbolic links and other types of files?

Читайте также:  Linux root ssh disable

What do you mean by «the first» file? First to be added to the directory, or first chronologically or as sorted using $LC_COLLATE , or something else?

5 Answers 5

To get the first file in the current dir you can put the expansion in an array and grab the first element:

files=(*) echo "$" # OR echo "$files" # since we are only concerned with the first element 

Assuming your current dir contains multiple dirs you can loop through and grab the first file like so:

for dir in *; do files=($dir/*) echo "$" done 

But be aware that, depending on your shell settings, files=(*) may return an array of one element (that is ‘*’) if there are no files. So you have to check that the file names in the array correspond to files which actually exist (and bear in mind that * is a valid file name).

This gives you the first name from the lexicographically sorted list of non-hidden names in the current directory. This may not be a regular file. In comments to the question, you specifically asked about regular files, though.

shopt -s nullglob set -- * printf "%s\n" "$1" 
  • first non-hidden file in locale collation order: first=(*(N[1]))
  • same, but restricted to non-directory files: first=(*(N^/[1]))
  • same, but also excluding symlinks to directories: first=(*(N^-/[1]))
  • restricting to regular files: first=(*(N.[1]))
  • same but including symlinks to regular files: first=(*(N-.[1]))
  • those define an array variable as it still needs to be able to store a variable number of elements: 0 (no matching file) or 1 (matching files, among which only the first is selected). To define a $first scalar variable instead (and have it contain the empty string if there’s no matching file), you can do () < first=$1; >*(N[1]) instead. Or to leave the $first scalar variable untouched instead if there’s no matching file: () < (($#)) && first=$1; >*(N[1]) .
  • to include hidden files, add the D glob qualifier
  • in some locales (including most of the ones typically used on GNU systems from 2020 like en_US.UTF-8 ), collation order is not always deterministic as some characters sort the same. See for instance after touch 🧙 🧚 🧛 🧜 🧝 on Ubuntu 20.04. All those files will have the same sorting order, so which one you’ll get first will me more or less random.
  • with zsh glob qualifiers, it’s also possible to change the order: n makes the filename comparison numerical (so that file2 comes before file10 for instance), and with the o glob qualifier, one can sort based on other criteria than name (such as age, size. ).
Читайте также:  Установить windows компьютер линукс

All existing answers seem to first create a full listing of the directory, which can take a while with thousands of elements, so I ended up with the simple:

Where -U means unsorted and thus produces an immediate result.

This also returns names that may not be regular files. Note that -U is a non-standard GNU extension. Using find . ! -name . may be better, but you still would only get the first part of the name if it contains newlines since head acts on text, not filenames.

You can use -f , seems to do the same and is standard. Filetypes are not a requirement here, but one could filter using file and test if needed. As for newlines, one can use —zero in ls, -z on head and -print0 on find (or use its exec flag).

To get the name of the regular file that sorts first in a directory, you may use

shopt -s nullglob dotglob unset -v name for name in some/path/*; do [ -f "$name" ] && break unset -v name done 

After this loop, $name would either be the name of the regular file that sorts first, or the variable would be unset if there are no regular files in the directory some/path .

The shell options used here make sure that the loop is not run if the pattern does not match ( nullglob ), and that we also match hidden names ( dotglob ).

You’ll get the first name since filename globbing patterns are expanded into lexicographically sorted lists.

Источник

Оцените статью
Adblock
detector