Câu trả lời:
mv
di chuyển một tệp và ln -s
tạo một liên kết tượng trưng, do đó, tác vụ cơ bản được hoàn thành bởi một tập lệnh thực thi hai lệnh này:
#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"
Có một vài hãy cẩn thận. Nếu đối số thứ hai là một thư mục, thì mv
sẽ di chuyển tệp vào thư mục đó, nhưng ln -s
sẽ tạo một liên kết đến thư mục chứ không phải là tệp đã di chuyển.
#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"
Một cảnh báo khác là đối số đầu tiên ln -s
là văn bản chính xác của liên kết tượng trưng. Nó liên quan đến vị trí của mục tiêu, không liên quan đến thư mục nơi lệnh được thực thi. Nếu vị trí ban đầu không có trong thư mục hiện tại và mục tiêu không được thể hiện bằng một đường dẫn tuyệt đối, liên kết sẽ không chính xác. Trong trường hợp này, đường dẫn cần phải được viết lại. Trong trường hợp này, tôi sẽ tạo một liên kết tuyệt đối (một liên kết tương đối sẽ tốt hơn, nhưng khó hơn để có được quyền). Kịch bản này giả định rằng bạn không có tên tệp kết thúc bằng ký tự dòng mới.
#!/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"
Nếu bạn có nhiều tệp, xử lý chúng trong một vòng lặp.
#!/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
có thể nhiều thông tin hơn cho người dùng đang di chuyển một tệp lớn ra khỏi đĩa có thể mất một thời gian.
Đặt tệp này trong tệp .sh và làm cho nó có thể thực thi được ( chmod +x filename
):
#!/bin/bash
mv "$1" "$2"
ln -s "$2" "$1"
Ví dụ sử dụng:
./test.sh asdf otherdir/asdf
Lưu ý rằng điều này không kiểm tra an toàn, vv Tùy thuộc vào mức độ phức tạp của nhiệm vụ của bạn, điều này có thể là đủ.
./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf
. Điều *
này dường như không làm việc với của bạn test.sh
. Bạn đã có một cách giải quyết? Thx
Tôi thường sử dụng chức năng một dòng này:
function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }
Cách sử dụng tương tự như mv hoặc cp:
ml old_file target_dir/new_file_name
Phá vỡ nó:
mkdir -p "$(dirname "$1")"
- tạo thư mục đích nếu nó chưa tồn tại
dirname "$1"
- lấy thành phần thư mục của đường dẫn (tước tên tệp)rsync -aP --no-links "$1" "$2"
- sao chép tập tin đến đích. Thay thế điều này bằng mv "$1" "$2"
nếu cả hai tệp nằm trên cùng một hệ thống tệp để có hiệu suất tốt hơn.
-a
- bảo vệ quyền sở hữu và tất cả các quyền khác. Bạn có thể điều chỉnh điều này để chỉ bảo quản các thành phần bạn muốn.-P
- cho thấy sự tiến bộ.--no-links
- không sao chép liên kết - điều này có nghĩa là bạn có thể chạy lệnh này bao nhiêu lần tùy ý trên cùng một tệp và bạn sẽ không bao giờ bị mất tệp của mình bằng cách vô tình ghi đè tệp đích của bạn bằng chính liên kết đó.ln -sf "$2" "$1"
- ghi đè tệp cũ bằng liên kết tượng trưng đến tệp mới
-s
- sử dụng các liên kết tượng trưng-f
- ghi đè tập tin cũ