I'm trying to write a bash script to iterate through a directory and run a command on every .py file to upload each to a different location based on its filename. [EDIT] - in the path/to/upload/$f, the $f needs to be the name of the file (without the extension)
I'm sure I'm miles off but might it look something like this:
cd /home/user/stuff
for f in $(find . -name '*.py')
do yes yes | [command] path/to/upload/$f
done
except here the whole path gets assigned to $f
the directory looks like:
├── zero
│ ├── ein
│ │ └── ein.py
├── one
│ ├── ban
│ │ └── ban.py
│ ├── deep
│ │ └── deep.py
etc...
So the first iteration would go [command] path/to/upload/ein
CodePudding user response:
Replace your line
for f in $(find . -name '*.py')
with
for f in $(find . | sort -r | grep "/${input}" | grep '.py$' )
This way, you will iterate on all python under ${input}.
I like to use "sort -r" as a visual prompt that I am working down to the start of the list. :-)
CodePudding user response:
If you've got Bash 4.0 (released in 2009) or later then you can use:
#! /bin/bash -p
shopt -s dotglob globstar nullglob
for f in **/*.py; do
yes yes | [command] "path/to/upload/${f##*/}"
done
shopt -s ...
enables some Bash settings that are required by the code:dotglob
enables globs to match files and directories that begin with.
.find
shows such files by default.globstar
enables the use of**
to match paths recursively through directory trees.nullglob
makes globs expand to nothing when nothing matches (otherwise they expand to the glob pattern itself, which is almost never useful in programs).
${f##*/}
expands to the value of$f
with everything up to and including the last/
character removed. See Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?)).
If you are stuck with an older version of Bash (e.g. on macOS) then another option is:
find . -name '*.py' -print0 \
| while IFS= read -r -d '' f; do
yes yes | [command] "path/to/upload/${f##*/}"
done
- See BashFAQ/001 (How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?) for an explanation of
find ... -print0 | while IFS= read -r -d '' ...
. See Bash Pitfalls #1 (for f in $(ls *.mp3)) for an explanation of why commonly-seen shell code for processing the output offind
is broken.