问题
I'm looking to search for files of a specific name, modify the name to the full path and then copy the results to another folder.
Is it possible to update each find result with the full path as the file name; i.e.
./folder/subfolder/my-file.csv
becomes
folder_subfolder_my-file.csv
I am listing the files using the following and would like to script it.
find . -name my-file.csv -exec ls {} \;
回答1:
Since you're using bash, you can take advantage of globstar
and use a for
loop:
shopt -s globstar # set globstar option
for csv in **/my-file.csv; do
echo "$csv" "${csv//\//_}"
done
shopt -u globstar # unset the option if you don't want it any more
With globstar
enabled, **
does a recursive search (similar to the basic functionality of find
).
"${csv//\//_}"
is an example of ${var//match/replace}
, which does a global replacement of all instances of match
(here an escaped /
) with replace
.
If you're happy with the output, then change the echo
to mv
.
回答2:
Just to demonstrate how to do this with find
;
find . -type f -exec bash -c '
for file; do
f=${file#./}
cp "$file" "./${f//\//_}"
done' _ {} +
The Bash pattern expansion ${f//x/y}
replaces x
with y
throughout. Because find
prefixes each found file with the path where it was found (here, ./
) we trim that off in order to avoid doing mv "./file" "._file"
. And because the slash is used in the parameter expansion itself, we need to backslash the slash we want the shell to interpret literally. Finally, because this parameter expansion syntax is a Bash-only extension, we use bash
rather than sh
.
Obviously, if you want to rename rather than copy, replace cp
with mv
.
If your find
does not support -exec ... +
this needs to be refactored somewhat (probably to use xargs
); but it should be supported on any reasonably modern platform.
回答3:
With perl's rename command ...
$ prename
Usage: rename [-v] [-n] [-f] perlexpr [filenames]
... you can rename multiple files by applying a regular expression. rename
also accepts file names via stdin:
find ... | rename -n 's#/#_#g'
Check the results and if they are fine, remove -n
.
来源:https://stackoverflow.com/questions/59678809/find-files-recursively-and-rename-based-on-their-full-path