I have many directories in a location with files of various extensions within them. The directories follow a standard convention but the files within do not. The solution I'm trying to come to is to rename the files within each folder based on a part of the directory they are located in for the list of folders I have to go through.

For example:

Directory: 001234@Redsox#17



[email protected]
[email protected]
[email protected]

Following through with each directory, renaming on just the appended code in the directory name. I have a basic framework already for operating through the process but I'm not sure how best to grab the part of the directory I need

for directory in *; do 
    pushd "$directory"
    for filename in *; do
        mv "$filename" "${target_filename}"

1 Answer 1


I would do something like this:

# nullglob
#    If set, Bash allows filename patterns which match no files to
# expand to a null string, rather than themselves.
shopt -s nullglob

# instead of looping through the dirs, loop through the files
# add al the possible extensions in the list
$ for f in */*.{doc,pdf,xls,txt}; do 
  # get the file dirname
  d=$(dirname "$f")
                  # using parameter expansion get the part
                  # of the dirname you need
  echo mv -- "$f" "$d/${d%%@*}@$(basename "$f")"

  # when you are satisfied with the result, remove the `echo`
$ ls -1 001234@Redsox#17/
[email protected]
[email protected]
[email protected]

  • That looks great! The only problem I get is a number of files don't process with 'basename: extra operand' returns. Many of the files I'm working with include a date in the filename....ie "File1 $ 10.26.2021.pdf" which might be gumming things up. Oct 26, 2021 at 21:41
  • @SomethingSomething I forgot to enclose the $f with double quotes, try with them, as edited in the answer. Oct 26, 2021 at 23:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .