Script that goes through files in a directory AND subdirectories - bash

I have a simple problem to which I don't find the answer on the net.
Like the title states it, I would like to go trough all the files in a directory AND his sub-directories. I know how to do it with find command but I would like to know how to do it with a simple for loop.
I initially have this line :
for file in $dir/*.png; do
And I'm sure there is a way to have some kind of $dir/*/*.png line that makes it possible with a for loop.
Thanks for your answers.

for file in $(find $dir - type f - name "*.png"); do

Related

How to iteratively rename files in Bash

I am trying to iterate over files in a folder, renaming them as foldername1, foldername2, etc. However, I'm getting an error which says that the mv isn't being used correctly.
So far my code looks like this:
FILES='(Full Path)/Macbeth/audio/'
for file in "$FILES"*
do
mv $file 'Macbeth'$i''
done
The final code should iterate through the files and rename them as, in this case Macbeth1.mp3, but I'm not sure how the Bash syntax works.
As suggested by Cyrus, the solution was to use the full path

Creating file that has the same name as a directory where the file is placed

I am using some script that converts one file format A into another B with a given name. I would like to write a script that is going to attribute to file B a name of directory where A is placed.
ex. If A is placed in a directory 1, after producing file B this file is going to have name 1.
I was reading a little bit about basename command but I am not even sure that I am on good track.
Thank you in advance.
Stefan
N.B. Can anyone of you could suggest me good practical tutorial concerning UNIX, scripts, BASH that could help me progress in this domain?
If your script was working with absolute path:
kent$ basename $(dirname /tmp/test/A)
test
If it is current path:
# we are in /tmp/test
kent$ basename $(pwd)
test

What is wrong in the for loop I use to create a file source=dest list?

I try to loop over the file I findin a relative path to build a list of relative path/soure file name=source file name
SHARED_LIB_PACK=""
for LIB in $(find ../level1/leve2/ -name "*.so*")
do
$SHARED_LIB_PACK=$SHARED_LIB_PACK" "$LIB"="${LIB##*/}
done
but as I run it, it complain :
line 6: = ../level1/level2/file.so.1.0=file.so.1.0: No such file or directory
Any help will be welcome
Firstly, variable assignment is done via:
FOO="bar"
and not
$FOO="bar"
The former will not work.
Secondly, your quotes seem to be in strange places:
SHARED_LIB_PACK=$SHARED_LIB_PACK" "$LIB"="${LIB##*/}
should probably be
LIB="${LIB##*/}"
SHARED_LIB_PACK="$SHARED_LIB_PACK $LIB"
or
SHARED_LIB_PACK="$SHARED_LIB_PACK ${LIB##*/}"

Bash find in current folder and #name# sub-folder recursively

Tricky question for a bash noob like me, but i'm sure this this easier that it seems to me.
I'm currently using the find command as follows :
run "find #{current_release}/migration/ -name '*.sql'| sort -n | xargs cat >#{current_release}/#{stamp}.sql"
in my capistrano recipe.
Problem is #{current_release}/migration/ contains subfolders, and I'd like the find command to include only one of these, depending on it's name (that I know, it's based on the target environment.
As a recap, folder structure is
Folder
|- sub1
|- sub2
and i'm trying to make a find specifying to recurse ONLY on sub1 for example. I'm sure this is possible, just couldn't find how.
Thanks.
Simply specify the directory you want as argument to find, e.g. find #{current_release}/migration/sub1 ....
EDIT: As per your clarification, you should use the -maxdepth argument for find, to limit the recursion depth. So, for example, you can use find firstdir firstdir/sub1 -maxdepth 1.
You just need to append that to your find invocation:
find #{current_release}/migration/sub_you_want -name ...
Depending on how you make the determination of the sub-directory you want, you should be able to script that as well.

batch rename files and folders at once

I got help regarding the following question:
batch rename files with ids intact
It's a great example of how to rename specific files in a group, but I am wondering if there is a similar script I could use to do the following:
I have a group of nested folders and files within a root directory that contain [myprefix_foldername] and [myprefix_filename.ext]
I would like to rename all of the folders and files to [foldername] and [filename.ext]
Can I use a similar methodology to what is found in the post above?
Thanks!
jml
Yes, quite easily, with find.
find rootDir -name "myprefix_*"
This will give you a list of all files and folders in rootDir that start with myprefix_. From there, it's a short jump to a batch rename:
find rootDir -name "myprefix_*" | while read f
do
echo "Moving $f to ${f/myprefix_/}"
mv "$f" "${f/myprefix_/}"
done
EDIT: IFS added per http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html
EDIT 2: IFS removed in favor of while read.
EDIT 3: As bos points out, you may need to change while read f to while read -d $'\n' f if your version of Bash still doesn't like it.

Resources