Find files ending with linux

Find all files ending in extension in bash

Write a bash script accepting two arguments: directory and extension. The script must print to stdout the path of all files in directory (and, recursively, its sub-directories) with a name ending with extension. So far I have:

find -type f -name ' *.extension * 

3 Answers 3

This script should do the trick:

#!/bin/bash find "$1" -type f -name "*.$2" 

Examples to run the script:

/bin/bash script.sh /srv/directory css /bin/bash script.sh '/srv/directory with space' css 

In this answer, I’m just giving some explanation for Viktor’s code.

This explanation might help those of you who are learning bash . Viktor updated his answer after I posted the «space issue» part and before I finished writing and saving this explanation. That’s what I hoped for.

It is very concise, and there are great explanations. The original code was:

#!/bin/bash #@filename: script.sh find $1 -type f -name "*.$2" 

It sounds like the question came from some kind of assignment, and I imagine that this original code might fulfill the assignment’s expectations. It will probably also work with most programs you will write, which is especially important if the question did not come from an assignment.

I often develop on Windows or Cygwin, so I run into paths and filenames that have spaces. If I use @Viktor’s code on Cygwin (note that the same behavior happens when I use Viktor’s code on linux)

$ pwd /home/bballdave025 #Write the program $ vim script.sh #view the program $ cat script.sh #!/bin/bash find $1 -type f -name "*.$2" #Create a path with spaces in one of the directory names #Name it after Viktor, for the great answer bballdave025@MYMACHINE ~ $ mkdir -p viktor/dir\ with\ spaces/directory #put some css files in that directory $ touch viktor/dir\ with\ spaces/directory/a.css $ touch viktor/dir\ with\ spaces/directory/b.css $ touch viktor/dir\ with\ spaces/directory/c.css # run Viktor's code, using the well-written instructions $ /bin/bash ./script.sh 'victor/dir with spaces/directory' css find: ‘viktor/dir’: No such file or directory find: ‘spaces/directory’: No such file or directory 

Note that I used ./script.sh rather than plain script.sh , because I had not set script.sh to be executable. I can run it as Viktor shows if I first run

Читайте также:  Linux mint мигает курсор

The problem comes from the way a bash shell and the find command handle spaces. With the first argument given simply as $1 , the spaces aren’t treated a special way. That’s probably not the best way to describe things. Perhaps a better way of explaining this concept is to show that bash will assign the following — i.e. bash will use an unintended assignment pattern — when the script is written as above.

$0='script.sh' $1='viktor/dir' $2='with' $3='spaces/directory' $4='css' 

[Note: what we want is to have things interpreted as]

$0='script.sh' $1='viktor/dir with spaces/directory' $2='css' 

[and we will get to how to accomplish this, later.]

This unintended assignment pattern will happen even if we tell bash that our directory has spaces

$ /bin/bash script.sh viktor/dir\ with\ spaces/directory css find: ‘viktor/dir’: No such file or directory find: ‘spaces/directory’: No such file or directory 

This can be seen by adding to the script the lines, echo «\$0 is $0» , echo «\$1 is $1» , echo «\$2 is $2» , and further with other lines having $(insert_number_here_but_no_parentheses) , if you’d like.

So, how do we fix this problem? Let’s look at the man page for find

$ man find # (press 'q' to get out of the display of the man page) 

Okay, that was kind of scary.

Let’s cut the original synopsis line down to

find [starting-point. ] [expression] 

What the DESCRIPTON means in its ‘starting-point’ explanation is that [starting-point. ] is a directory (or directories) from which you’ll start your search. For now, just take it at face value that ‘expression’ is something that restricts the search — in your case, you look for only files and then further filter the results by specifying that they have a certain file-extension.

Читайте также:  Tew 648ub драйвер linux

Let’s get back to the find $1 -type f -name «*.$2» command. The main point to know here is that the command as shown here will be expanded to

find viktor/dir with spaces/directory -type f -name "*.css" 

The «space problem» is that it will be interpreted by find and by the shell as follows

find victor/dir with spaces/directory -type f -name "*.css" | \ | \ `--------------------' | \ | \ / | | | \ Another '[expression]' (2) | | | -- Another '[starting-point]' | | -- '[expression]' (1) | -- '[starting-point]' (supposedly a directory) -- Command name 

Note that our ‘[expression]’ (1) and ‘[expression]’ (2) don’t factor into what happens because the two ‘[starting-place]’ paths fail.

What’s now shown in Viktor’s code

#!/bin/bash #@filename viktor_script.sh find "$1" -type f -name "*.$2" 
find "viktor/dir with spaces/directory" -type f -name "*.css" `--' `--------------------------------' `-------------------' | | / | | valid '[expression]' to define | | a "filter" for files outputted | | | -- '[starting-point]' (a real directory) | bash knows to include the spaces because -- command name of the quotation marks 

Let’s run it, first making sure it’s executable

$ chmod +x viktor_script.sh $ /bin/bash ./viktor_script.sh css $ /bin/bash viktor_script.sh 'viktor/dir with spaces/directory' css viktor/dir with spaces/directory/a.css viktor/dir with spaces/directory/b.css viktor/dir with spaces/directory/c.css 

Источник

Recursively find files ending with specified pattern

I have a lot of folders with files ending with «-105×135.jpg», «-410×410.jpg» etc., «780-105×135.jpg» and «candyswing-2-klein-ohrringe-schale-038-135×160.jpg» for example which i need to find and delete, using online regex I’ve created this pattern: 8x..9.jpg , but find . -regex ‘2x..1.jpg’ didn`t show any results.

2 Answers 2

According to the man page, the -regex option is a match on the entire path, ie. the entire file name and also the entire directory-path portion, so you would need to precede your regex with .* . There are several explicit examples in the man page.

Читайте также:  Линукс узнать дату установки

Also, keep in mind the option -regextype . The default (per the man page) is emacs , but other options are posix-awk , posix-basic , posix-egrep and posix-extended . Knock yourself out.

Thanks! It did work, but besides adding .* I needed to replace periods with 8 , for some reason periods didn’t work. I ended up with find -regex «.*[09]x413.jpg»

Great to hear. If you’re game to continue experimenting, try «.*[09]x7+.jpg» and «.*[09]x3<3>.jpg»

Another option would be to use bash’s globstar option:

The glob pattern above is slightly different that the regex you provided; the regex would allow any two characters after the x , not strictly numbers. In other words, a file named: somefile-135xyz9.jpg would match the regex, but not the above glob.

The glob recursively ( ** ) matches files that:

  • start with anything ( * )
  • have three numbers (three 6 )
  • followed by an x
  • followed by three numbers
  • followed by .jpg

One risk to this approach is if/when the number of matching files exceeds the command-line argument space. In that case, you could save the filenames in an array, then loop through the array individually.

files=(**/*922x256.jpg) for file in "$"; do echo Would: rm -- "$file"; done 
files=(**/*779x119.jpg) for file in "$"; do rm -- "$file"; done 

Источник

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