This find (GNU) should work:
find . -type f -newermt 2014-03-30 ! -newermt 2014-04-01 -exec bash -c 'f="$1"; n="bc.${f##*.}"; mv "$f" "$n"' - '{}' \;
题
I wish to rename multiple (many) files, according to their modification datetime. That is, I wish to provide a date (say, 2014-31-03
), and for that date, replace the substring a
to the substring bc
in any of the files whose modification date was that date.
For example, suppose the output of ls -latr --time-style=long-iso
is as follows:
total 8
drwxrwxr-x 3 bach bach 4096 2014-04-01 10:02 ..
-rw-rw-r-- 1 bach bach 0 2014-03-31 10:02 a.1
-rw-rw-r-- 1 bach bach 0 2014-03-31 10:02 a.2
-rw-rw-r-- 1 bach bach 0 2014-03-31 10:02 bc.1
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 a.3
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 bc.2
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 bc.3
drwxrwxr-x 2 bach bach 4096 2014-04-01 10:08 .
then the output after the modification should be as follows:
total 8
drwxrwxr-x 3 bach bach 4096 2014-04-01 10:02 ..
-rw-rw-r-- 1 bach bach 0 2014-03-31 10:02 bc.1
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 a.3
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 bc.2
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:02 bc.3
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:12 bc.1
-rw-rw-r-- 1 bach bach 0 2014-04-01 10:12 bc.2
drwxrwxr-x 2 bach bach 4096 2014-04-01 10:12 .
I do not care about the case for which there is more than one appearance of the substring a
in the name of a file. It's ok if it will replace only the first occurrence. If it makes it much easier, I'm also ok with assuming the substring appears at the beginning of the filename, but I can't assume it is of fixed length.
解决方案
This find (GNU) should work:
find . -type f -newermt 2014-03-30 ! -newermt 2014-04-01 -exec bash -c 'f="$1"; n="bc.${f##*.}"; mv "$f" "$n"' - '{}' \;
其他提示
Here is another one using find
and bash parameter expansion inside a loop:
$ ls
a.file1.txt a.file2.txt a.file3.txt b.file4.txt
b.file5.txt b.file6.txt c.file7.txt c.file8.txt c.file9.txt
$ files=($(find . -type f -newermt 2014-04-01 ! -newermt 2014-04-02))
$ for file in "${files[@]}"; do
> [[ "$file" =~ a. ]] && mv "$file" "${file/a./bc.}"
> done
$
$ ls
b.file4.txt b.file5.txt b.file6.txt bc.file1.txt
bc.file2.txt bc.file3.txt c.file7.txt c.file8.txt c.file9.txt