`find -name`与regex模式和文件名替换使用`cp` [英] `find -name` with regex pattern and filename replacement using `cp`
问题描述
目前我使用 cron
中的命令将 *。data
的副本从源路径复制到目标路径:
find / source_path -name * .data -exec cp {} / target_path \;
源结构是:
/source_path/category1/001.data
/source_path/category1/002.data
/source_path/category2/003.data
/ source_path / category3 / 004 .data
/source_path/categorya/005.data
/source_path/categoryb/006.data
在上面的 cron
命令之后,目标将包含:
/target_path/001.data
/target_path/002.data
/target_path/003.data
/target_path/004.data
/target_path/005.data
/target_path/006.data
我需要一个单行解决方案来替换我当前的cron命令,以便执行后,目标将包含:
/target_path/category1_001.data
/ target_path / category1_002 .data
/target_path/category2_003.data
/target_path/category3_004.data
/target_path/categorya_005.data
/target_path/categoryb_006.data
将子目录名称附加为目标文件名的前缀。
感谢。
检查此命令只打印字符串:
$ find / source_path -name \ * .data | while read -r filename; do printf打印版本:cp%s%s\\\
$ {filename}$(printf%s\\\
$ {filename}| seds /^.*[/] \\(category [^ /] * \)[/] \(。* [。] data \)$ / \ / target_path\ / \1_\2 /) done
find 命令打印找到的文件名, p>
读取-r filename 读取一行文本并将其存储到文件名变量中。
find ... |同时读取-r filename ,将一行文件名列表写入管道。一次只能读取一个文件名。
sed 命令会更改路径名称 strong> /source_path/category1/001.data 键入 /target_path/category1_001.data 。
sed 的字符串参数,但如果您在这些主题中介入,您应该阅读:
s / 是搜索和替换sed命令,后面是3个元素:s / regex pattern / replacement / flag
^ 在开始时表示行的开头。
。任何一个字符。
* 表示之前指定的字符的0或无限数。
[/]表示一个字符,字符 / 。 []用于转义 / ,否则会解释为正则表达式,替换和标记 。
全部 ^。* [/] 表示以任何零个或多个字符开头的行。此开始序列必须以 / 结尾。
[^ /]表示一个字符, ^ 部分的char列出。因此,它表示除 / 之外的任何一个字符。
[abc]介于[]之间,表示一个字符: 。
正则表达式中遇到的第一个 \(。* \) strong> \1 中的替换。 正则表达式中遇到的第二个 \(。* \)可通过替换中的 \2 <强>。如果没有 \ 转义字符,()表示单个字符 完成后使用 cp 可有效地复制文件: Currently I'm using the command in The source structure is: After the above I need a one-line solution to replace my current cron command, so that after execution, the target will contain: To append sub-directory name as a prefix of the target filename. Thanks. Check this command which only prints strings: find command prints the filenames found, one per line. read -r filename read one line of text and store it into filename variable. find ... | while read -r filename all together, write a list of filenames, one per line, into the pipe. Only one filename is read at a time. For each filename read, the command into the while block is executed. The sed command changes a pathname /source_path/category1/001.data into /target_path/category1_001.data. I tried my best to explain the string argument of sed in the lines below, but if you are interresting in these topics you should read: s/ is the search and replace sed command and it is followed with 3 elements: "s/regex pattern/replacement/flag" ^ at the very start means, start of the line. . means any one char. * means 0 or infinite number of the char specified just before. [/] means one char, the char /. [] are used to escape / otherwise it is interpreted as a delimiter between regex pattern, replacement, and flag. Alltogether ^.*[/], means a line starting with any zero or more chars. This starting sequence must end with /. [^/] means one char, ^ at start means not part of the char listed. So, it means any one char except the /. [abc] between [], means one char: either a either b either c. The first \(.*\) encountered in the regex pattern can be referenced with \1 in replacement. The second \(.*\) encountered in the regex pattern can be referenced with \2 in replacement. etc. Without \ escape char, ( means a single char When done use cp instead to effectively copy the files:
这篇关于`find -name`与regex模式和文件名替换使用`cp`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!(
,且无法引用内容。 / p>
find / source_path -name \ * .data | while read -r filename; do cp$ {filename}$(printf%s\\\
$ {filename}| sed s /^.* [/] \(category [^ /] * \)[/] \(。* [。] data\)$ / \ / target_path \ / \1_\ 2 /); done
cron
to make copy of *.data
from source to target path:find /source_path -name *.data -exec cp {} /target_path \;
/source_path/category1/001.data
/source_path/category1/002.data
/source_path/category2/003.data
/source_path/category3/004.data
/source_path/categorya/005.data
/source_path/categoryb/006.data
cron
command, the target will contain: /target_path/001.data
/target_path/002.data
/target_path/003.data
/target_path/004.data
/target_path/005.data
/target_path/006.data
/target_path/category1_001.data
/target_path/category1_002.data
/target_path/category2_003.data
/target_path/category3_004.data
/target_path/categorya_005.data
/target_path/categoryb_006.data
$ find /source_path -name \*.data | while read -r filename; do printf "print version: cp %s %s\n" "${filename}" "$(printf "%s\n" "${filename}" | sed "s/^.*[/]\(category[^/]*\)[/]\(.*[.]data\)$/\/target_path\/\1_\2/")"; done
(
, and the content cannot be referenced.find /source_path -name \*.data | while read -r filename; do cp "${filename}" "$(printf "%s\n" "${filename}" | sed "s/^.*[/]\(category[^/]*\)[/]\(.*[.]data\)$/\/target_path\/\1_\2/")"; done