背景
在 Linux 中您可以:
- 使用以下命令列出一组文件
ls Filename*
- 使用以下方法删除一组文件
rm Filename*
- 使用以下方式移动一组文件
mv Filename* /New/Directory
- 但是你不能复制一组文件:
cp Filename* *.bak
更改Linuxcp
命令来复制文件组
我有一组文件想要复制,而不必逐个输入名称并使用以下cp
命令:
$ ls gmail-meta3*
gmail-meta3 gmail-meta3-REC-1558392194-26467821
gmail-meta3-LAB-1558392194-26467821 gmail-meta3-YAD-1558392194-26467821
我如何使用类似旧的 DOS 命令copy gmail-meta3* *.bak
?
我不想输入四次类似的命令:
cp gmail-meta3-LAB-1558392194-26467821 gmail-meta3-LAB-1558392194-26467821.bak
我正在寻找一个脚本/函数/应用程序,它接受新旧文件名组的参数,而不是带有硬编码文件名的参数。例如,用户可以输入:
copy gmail-meta3* *.bak
或者他们可能会输入:
copy gmail-meta3* save-*
答案1
下面是一个非典型用法的示例sed
,适用于这种情况:
sed -i.bak '' file-prefix*
这样,实际上sed
不会更改文件,因为我们没有提供任何命令''
,但由于该选项,-i[suffix]
它将创建每个文件的备份副本。我在询问时发现了这种方法 有没有办法创建文件的备份,而无需输入两次其名称?
答案2
您可以使用find
:
find . -max-depth 1 -name 'gmail-meta3*' -exec cp "{}" "{}.bak" \;
这将在当前目录中查找.
名称与 glob 模式匹配的所有文件(请注意模式周围的单引号,以防止 shell 通配符)。对于找到的每个文件,它将cp
从名称执行到 name.bak。末尾的 \; 确保它将单独执行每个文件,而不是一次传递所有文件。最大深度为 1 仅搜索当前目录,而不是向下递归。
答案3
您可以使用for
循环bash
。通常,我只会将其输入为一行,因为这不是我经常执行的任务:
for f in test* ; do cp -a "$f" "prefix-${f}.ext" ; done
但是,如果您需要它作为脚本:
cps() {
[ $# -lt 2 ] && echo "Usage: cps REGEXP FILES..." && return 1
PATTERN="$1" ; shift
for file in "$@" ; do
file_dirname=`dirname "$file"`
file_name=`basename "$file"`
file_newname=`echo "$file_name" | sed "$PATTERN"`
if [[ -f "$file" ]] && [[ ! -e "${file_dirname}/${file_newname}" ]] ; then
cp -a "$file" "${file_dirname}/${file_newname}"
else
echo "Error: $file -> ${file_dirname}/${file_newname}"
fi
done
}
使用方法与 类似 rename
。测试方法如下:
pushd /tmp
mkdir tmp2
touch tmp2/test{001..100} # create test files
ls tmp2
cps 's@^@prefix-@ ; s@[email protected]@' tmp2/test* # create backups
cps 's@[email protected]@' tmp2/test* # more backups ... will display errors
ls tmp2
\rm -r tmp2 # cleanup
popd
答案4
仅限 rsync 的解决方案
如果你只是想备份文件,你可以将它们复制到新目录
rsync /path/to/dir/Filename* /path/to/backupdirectory
这会将Filename
文件从复制/path/to/dir/
到/path/to/backupdirectory
。
rsync + 文件重命名
如果您希望备份文件有后缀,事情就会变得复杂起来rsync
......
rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak
这将用现有文件()覆盖现有文件...-I
但前提是它们(-u
)较新(但事实并非如此)并创建带有后缀的备份。
您也可以在同一目录中执行此操作。但最好排除现有备份。
rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak --exclude '*.bak'