Answers:
mv
移动文件并ln -s
创建符号链接,因此基本任务是通过执行以下两个命令的脚本来完成的:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
有一些警告。如果第二个参数是目录,则会mv
将文件移至该目录,但ln -s
会创建指向该目录的链接,而不是指向已移动文件的链接。
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
另一个需要注意的是,第一个参数ln -s
是符号链接的确切文本。它是相对于目标位置的,而不是相对于执行命令的目录。如果原始位置不在当前目录中,并且目标没有由绝对路径表示,则链接将不正确。在这种情况下,需要重写路径。在这种情况下,我将创建一个绝对链接(相对链接会更可取,但更难做到正确)。该脚本假定您没有以换行符结尾的文件名。
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
case "$original" in
*/*)
case "$target" in
/*) :;;
*) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
esac
esac
ln -s -- "$target" "$original"
如果您有多个文件,请循环处理它们。
#!/bin/sh
while [ $# -gt 1 ]; do
eval "target=\${$#}"
original="$1"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
case "$original" in
*/*)
case "$target" in
/*) :;;
*) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
esac
esac
ln -s -- "$target" "$original"
shift
done
rsync --remove-source-files
可能对从磁盘上移出大文件的用户可能会花费一些时间提供更多信息。
将其放在.sh文件中并使其可执行(chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
用法示例:
./test.sh asdf otherdir/asdf
请注意,这不会进行安全检查等。根据您的任务复杂程度,这可能就足够了。
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
?本*
似乎并不与你的工作test.sh
。您有解决方法吗?Thx
我通常使用此单行函数:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
用法类似于mv或cp:
ml old_file target_dir/new_file_name
分解:
mkdir -p "$(dirname "$1")"
-创建目标目录(如果尚不存在)
dirname "$1"
-获取路径的目录部分(带文件名)rsync -aP --no-links "$1" "$2"
-将文件复制到目标位置。mv "$1" "$2"
如果两个文件都在同一文件系统上,则用替换为更好的性能。
-a
-保留所有权和所有其他权限。您可以对其进行调整以仅保留所需的组件。-P
-显示进度。--no-links
-不要复制链接-这意味着您可以在同一文件上多次运行此命令,并且永远不会因使用符号链接自身意外覆盖目标文件而丢失文件。ln -sf "$2" "$1"
-用符号链接覆盖旧文件到新文件
-s
-使用符号链接-f
-覆盖旧文件