SIRBA
SIRBA

Reputation: 23

Looping through all files with specific extension and execute something on them

This is my first hours with Linux shell script and it seems really powerful but i am still a little confused.

I want to loop through all the files with a specific extension in a directory recursively (all subdirectories, subsubdirectories and ...) and by running an executable on them produce a new file with same name but different extension on exact location of the original file.

Following is the pseudo code for it:

files = list of all files (full path not just names) with extension .ext recursively

for file in files
    executable -option1 -option2 fullpath/file.ext1 > fullpath/file.ext2

Upvotes: 1

Views: 2888

Answers (2)

chepner
chepner

Reputation: 532238

In bash 4 or later, you can take advantage of the globstar option, which is set by default.

for file in **/*.ext1; do
    executable -option1 -option2 "$file" > "${file%.ext1}".ext2
done

Upvotes: 5

William Pursell
William Pursell

Reputation: 212604

  find . -name '*.ext1' -type f -exec sh -c \
    'executable -option1 -option2 ${0} > ${0%.ext1}.ext2' {} \;

find is a standard tool for recursively walking a file tree. The first argument (in this case '.', meaning the current working directory) specifies the base of the tree at which to begin the descent. The -name argument limits the scope of the search to files that match the given filename. The -type f further limits the search to regular files (as opposed to directories or other entities). The -exec option instructs find to execute the specified command on every file it finds that matched the previous specifications (regular files whose name ends in ".ext1") We use sh to execute the command rather than directly calling the executable for 2 reasons: it is easy to manipulate the filename, and because it is not strictly portable to even try to manipulate the filename with find: it must be given exactly as {}.

The ${0%.ext1} is shell syntax that takes the filename (the value of $0 is the filename, since we pass it as the first argument to sh via {} in find) and strips off the trailing ".ext1". We append ".ext2" to that resulting string to get the desired output file.

Upvotes: 6

Related Questions