这个问题是我之前的问题的续集,使用mkdir.
我正在使用bash外壳。我创建了五十个目录,每个目录都以前缀“s”开头,使用以下命令:
mkdir $(printf "s%02i " $(seq 1 50))
Run Code Online (Sandbox Code Playgroud)
用零填充到第二个数字。也就是说,我获得的目录的形式为s01, s02, ..., s49, s50。
现在我想使用cp将单个文件(例如,test.txt)复制到五十个目录中的每一个。是否有可能以类似于上面的方式做到这一点?例如,以下是否可行?我对 Unix/Linux 比较陌生,所以我真的不想尝试这个,直到有人告诉我它是安全的。
cp test.txt $(printf "s%02i.txt " $(seq 1 50))
查看man页面cp,它看起来不像cp支持这样的多个目的地,但是:
NAME
cp - copy files and directories
SYNOPSIS
cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
DESCRIPTION
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
Mandatory arguments to long options are mandatory for short options
too.
Run Code Online (Sandbox Code Playgroud)
您还可以让 shell 使用for循环进行迭代。这是最基本的方法,不依赖于parallel或等外部工具xargs,我发现它最容易理解:
for name in $(printf "s%02i " $(seq 1 50)); do
mkdir $name
cp test.txt $name
done
Run Code Online (Sandbox Code Playgroud)
还有一百万种其他方式来写这个,例如:
for name in $(seq -w 1 50); do
mkdir s$name
cp test.txt s$name
done
Run Code Online (Sandbox Code Playgroud)
如果您想在执行之前验证将执行的内容,您可以执行一些操作,例如在命令前加上echo,这将打印该行而不是执行它:
for name in $(seq -w 1 50); do
echo mkdir s$name
echo cp test.txt s$name
done
Run Code Online (Sandbox Code Playgroud)
输出:
mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.
Run Code Online (Sandbox Code Playgroud)
如果您想使用命令的输出将文件复制到每个目录cp,您可以始终将其通过管道传输到xargs:
printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt
Run Code Online (Sandbox Code Playgroud)
不应该担心解析输出的安全性,因为您事先知道它的格式和内容——在文件名中遇到元字符和空格的风险在这里并不是真正的问题。
或者,假设目录已经存在,您可以尝试以下操作:
find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}
Run Code Online (Sandbox Code Playgroud)
或没有管道:
find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;
Run Code Online (Sandbox Code Playgroud)
最后两个命令将查找当前目录中的任何文件并找到cp test.txt它们。该-maxdepth 1选项也将避免接收文件的任何子目录。请注意,'s[0-9][0-9]'匹配s后跟任意两位数字,这意味着如果由于某种原因您s99在 中cwd,它也会收到test.txt.
| 归档时间: |
|
| 查看次数: |
11989 次 |
| 最近记录: |