问题
I have a file structure like this:
- 00000010
- 000000001.file1
- 000000001.file2
- 00000020
- 00000003.file1
- 00000003.file2
- 00000003.file3
- ...
So there are folders with 8-digit names containing one ore more files with name starting with 8-digit numbers. But theses filenames are – let's say – out of sync. So Now I try to rename them recursively in bash to archive:
- 00000010
- 000000010.file1
- 000000010.file2
- 00000020
- 00000020.file1
- 00000020.file2
- 00000020.file3
- ...
My script does look like:
#! /bin/bash
find * -maxdepth 1 -name "*" -type d | while read -r dir
do
rename 's/$dir\/[0-9]{8}/$dir/' *
done
But this is not working and gives errors like
Global symbol "$dir" requires explicit package name at (eval 1) line 1.
How could I write it to rename the files according to their folder names?
Thank you for help!
回答1:
Use "
in place of '
in rename
You should run rename
on the files inside $dir
, so the argument to rename
must be $dir/*
and not just *
Since you want to replace dir/8digits
with dir/dir
the replacement part of the regex should be $dir\/$dir
With the above changes the command looks like:
rename "s/$dir\/[0-9]{8}/$dir\/$dir/" $dir/*
回答2:
rename
is actually a Perl script.
Here's how you could do it using only bash
and mv
:
#!/bin/bash
for dir in *; do
if test -d "$dir"; then
(
cd $dir
for file in *; do
newfile=$dir.${file#*.}
mv "$file" "$newfile"
done
)
fi
done
First a script to reproduce your directory tree:
$ i=1
$ for dir in 000000{1..2}0; do
mkdir $dir
touch $dir/0000000$i.file{1..3}
i=$((i+1))
done
$ find .
.
./00000010
./00000010/00000001.file1
./00000010/00000001.file2
./00000010/00000001.file3
./00000020
./00000020/00000002.file3
./00000020/00000002.file2
./00000020/00000002.file1
And now showing the script working:
$ ../ren.sh
$ find .
.
./00000010
./00000010/00000010.file1
./00000010/00000010.file2
./00000010/00000010.file3
./00000020
./00000020/00000020.file1
./00000020/00000020.file2
./00000020/00000020.file3
回答3:
First, *
in your find command is misplaced -- you need to give a directory to start searching. .
is usual.
Second, $dir
in your perl rename command won't be expanded by the shell because the whole string is quoted.
Third, the *
you are handing to your perl rename command will expand to all the directories and files in your current working directory, which is probably not what you intended.
@Mikel's answer is much nicer than what I was working on, but I thought this might still be useful. :)
来源:https://stackoverflow.com/questions/4861208/shell-script-to-rename-multiple-files-from-their-parent-folders-name