Перемістіть файл і залиште м'яке посилання позаду


10

Я шукаю одну команду Linux, яка дозволяє мені робити еквівалент цього:

cp /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Якщо його немає, який найкращий спосіб зробити це для купи файлів?


Я не знаю сценаріїв Bash досить добре, щоб написати його, але моїм рішенням було б просто написати сценарій і назвати його чимось захоплюючим, як cpln
Unkwntech

1
Не повинен cp бути mv?
Барт ван Хекелом

Ні. Варіант -f ln опікується цим.
innaM

1
спробуйте його на 10 Гб файлі
hayalci

2
@HelloGoodbye Ти плутаєш &&з &. Як написано, рядок перевіряє повернене значення cp і виконує лише другу частину, якщо це вдалося.
ісадок

Відповіді:


7

Невелика примітка - це те, що ви можете використовувати ln обидва рази, щоб команда фактично не переміщувала дані (якщо припустити, що обидва шляхи знаходяться в одній файловій системі).

ln /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Але я припускаю, що ви хочете перемістити вміст / some / path / на інший диск, а потім створити посилання на нові файли, щоб "ніхто" не помічав.

for f in `ls /some/path/`; do ln /some/path/$f /another/path/ && ln -sf /another/path/$f /some/path; done

Загортання його у функцію bash:

function cpln {
    for f in `ls $1`
    do
        ln $1/$f $2 && ln -sf $2/$f $1
    done
}

Чи є спосіб зробити цю роботу, якщо те, що я рухаю, стане каталогом?
Тладуке

Як це переміщує фактичний файл на диску?
Ібрагім

Ібрагім: дані не переміщуються, вони просто оновлюють покажчики в каталозі.
Містер Шарк

Тладуке: Так і ні. Оскільки каталог на дисках набагато менший, немає необхідності в фокусі ln (який не працює для Directorys), просто зробіть mv :-)
Містер Шарк

2

Мій сценарій, який ви можете використовувати (займає два параметри / деякі / шлях / файл та / інший / шлях /):

#!/bin/bash
cp $1 $2
if [ "$?" -ne "0" ]; then
    echo "Some error"
    exit 1
    fi
ln -sf $2/${1##*/} ${1%/*}

Прохолодний трюк із стринг-маніпуляціями, ніколи цього не бачив. Дякую!
itadok

1

Серйозно, я думав, що це було дійсно легке питання.

Ось що я можу зробити в perl:

#!/bin/perl
# Usage: cpln TARGETDIR SOURCE...
# Example: find tree/ -type f | xargs cpln commands/

$target = shift;

foreach(@ARGV) {
    m[(.*)/([^/]+)];
    system("cp $_ $target");
    system("ln -sf $target/$2 $1/");
}

Я сподівався на щось більш елегантне, але, мабуть, я цим скористаюся.


1
Щоб зробити це "в Perl", ви повинні використовувати File :: Copy (або подібне) та symlink (). Perl - не оболонка; уникайте system (), а особливо уникайте передачі цілих командних рядків до системи () (наприклад, що робити, якщо аргумент містить пробіл?). Так чи інакше, завжди, завжди, ЗАВЖДИ перевіряйте повернені значення.
Джон Сіракуза
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.