将文件复制到目标并创建目标(如果不存在)
Copy files to destination and create destination if does not exist
我正在写一个bash脚本来复制一个或多个或所有 文件到目的地,如果目的地不存在则创建。
我已经完成了这个 solution 但它没有完成我的要求。
我的代码(由于 idk 什么原因不起作用):
# copy files and make a directory if does not exist
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
# if file is last argument (directory) then break loop
if [ "$file" == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
我希望所有这些命令都能正常工作:
# copies "text.txt" to "testdir" (testdir may or may not exist so it must be created first)
$ mkcp test.txt ~/desktop/testdir
# copies "test1.txt" and "test2.txt" to "testdir" (conditions are same)
$ mkcp test1.txt test2.txt ~/desktop/testdir
# copies "all files" to "testdir" (conditions are same)
$ mkcp * ~/desktop/testdir
如果有任何其他解决方案可以完成我的要求,我也可以。
注:mkcp
函数存储在.zshrc
.
这是我建议的主要更改:
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
# if file is last argument (directory) then break loop
if [ "$file" == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
我不清楚您是如何收到错误消息的mkcp:9: = not found
;要调试它,我需要查看您修改后的代码。 OTOH,我不相信调试会特别有建设性。
这个命令有错误
# copies "all files" to "testdir" (conditions are same)
$ mkcp * ~/desktop/testdir
您正在将字符串“*”作为命令传递给自定义函数,因此当您发送
*mkcp * 你实际上是在说 "cp -R * /path" 其中 * 只是一个字符串,而不是 'all'.
您可以尝试这样做:
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
if [[ "${file}" == "*" ]]; then
LIST_FILE=$(ls $dir)
for i in $LIST_FILE
do
cp $i $dir
done
break
fi
# if file is last argument (directory) then break loop
if [ file == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
如果您需要 'debug' 脚本正在执行什么,请尝试 运行 脚本为:
bash -x mkcp * ~/desktop/testdir
-x 将如何执行脚本的每个步骤。
在我意识到这是一个 zsh 问题之前,我添加了这个 bash 答案。没有删除它,希望其他人发现它有用。
您可以使用 ${var:offset:length}
扩展获取位置参数的子列表。请参阅手册中的 Shell Parameter Expansion。
也许是这样:
mkcp() {
local dir="${@: -1}"
mkdir -p "$dir"
for file in "${@:0:$#}" # all but last
do
cp -vR "$file" "$dir"
done
}
事实上,它可以更简单,假设你有 GNU cp 和 -t
选项:
mkcp() {
local dir="${@: -1}"
mkdir -p "$dir"
cp -t "$dir" -vR "${@:0:$#}"
}
我添加了 cp 的 -v
选项以更加详细,因此您可以看到正在复制哪些文件。
您假设最后一个参数必须是一个目录,如果不存在这样的目录,则应该创建一个。在 zsh 中,我会这样做:
mkcp() {
local destdir=$@[-1]
if [[ -f $destdir ]]
then
echo Missing destination directory 2>&1
return 1
else
mkdir -p $destdir
if [[ -d $destdir ]]
then
cp "$@"
else
echo Can not create $destdir
return 1
fi
fi
}
问题不在于复制(普通的cp
命令就可以完成,不需要循环),所以这里的重点是错误检查。
请注意,使用我的方法,开关可以隐式传递给 cp
,例如
mkcp -r foo bar baz
也递归复制子目录,并且
mkcp -rv foo bar baz
另外打印复制的文件的名称。
我正在写一个bash脚本来复制一个或多个或所有 文件到目的地,如果目的地不存在则创建。
我已经完成了这个 solution 但它没有完成我的要求。
我的代码(由于 idk 什么原因不起作用):
# copy files and make a directory if does not exist
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
# if file is last argument (directory) then break loop
if [ "$file" == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
我希望所有这些命令都能正常工作:
# copies "text.txt" to "testdir" (testdir may or may not exist so it must be created first)
$ mkcp test.txt ~/desktop/testdir
# copies "test1.txt" and "test2.txt" to "testdir" (conditions are same)
$ mkcp test1.txt test2.txt ~/desktop/testdir
# copies "all files" to "testdir" (conditions are same)
$ mkcp * ~/desktop/testdir
如果有任何其他解决方案可以完成我的要求,我也可以。
注:mkcp
函数存储在.zshrc
.
这是我建议的主要更改:
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
# if file is last argument (directory) then break loop
if [ "$file" == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
我不清楚您是如何收到错误消息的mkcp:9: = not found
;要调试它,我需要查看您修改后的代码。 OTOH,我不相信调试会特别有建设性。
这个命令有错误
# copies "all files" to "testdir" (conditions are same)
$ mkcp * ~/desktop/testdir
您正在将字符串“*”作为命令传递给自定义函数,因此当您发送 *mkcp * 你实际上是在说 "cp -R * /path" 其中 * 只是一个字符串,而不是 'all'.
您可以尝试这样做:
mkcp() {
# last argument is destination
dir="${@: -1}"
# create directory if does not exist
mkdir -p "$dir"
# loop over all arguments
for file in "$@"
do
if [[ "${file}" == "*" ]]; then
LIST_FILE=$(ls $dir)
for i in $LIST_FILE
do
cp $i $dir
done
break
fi
# if file is last argument (directory) then break loop
if [ file == "$dir" ]; then
break
fi
# else keep copying files
cp -R "$file" "$dir"
done
}
如果您需要 'debug' 脚本正在执行什么,请尝试 运行 脚本为:
bash -x mkcp * ~/desktop/testdir
-x 将如何执行脚本的每个步骤。
在我意识到这是一个 zsh 问题之前,我添加了这个 bash 答案。没有删除它,希望其他人发现它有用。
您可以使用 ${var:offset:length}
扩展获取位置参数的子列表。请参阅手册中的 Shell Parameter Expansion。
也许是这样:
mkcp() {
local dir="${@: -1}"
mkdir -p "$dir"
for file in "${@:0:$#}" # all but last
do
cp -vR "$file" "$dir"
done
}
事实上,它可以更简单,假设你有 GNU cp 和 -t
选项:
mkcp() {
local dir="${@: -1}"
mkdir -p "$dir"
cp -t "$dir" -vR "${@:0:$#}"
}
我添加了 cp 的 -v
选项以更加详细,因此您可以看到正在复制哪些文件。
您假设最后一个参数必须是一个目录,如果不存在这样的目录,则应该创建一个。在 zsh 中,我会这样做:
mkcp() {
local destdir=$@[-1]
if [[ -f $destdir ]]
then
echo Missing destination directory 2>&1
return 1
else
mkdir -p $destdir
if [[ -d $destdir ]]
then
cp "$@"
else
echo Can not create $destdir
return 1
fi
fi
}
问题不在于复制(普通的cp
命令就可以完成,不需要循环),所以这里的重点是错误检查。
请注意,使用我的方法,开关可以隐式传递给 cp
,例如
mkcp -r foo bar baz
也递归复制子目录,并且
mkcp -rv foo bar baz
另外打印复制的文件的名称。