Используя Bash, как передать список файлов в «ln -s» без использования «найти»?

Я хочу создать символические ссылки на все файлы в «myfiles», которые еще не связаны, и указать папку назначения для только что созданных символических ссылок.

Я успешно использую следующий cmd для создания списка существующих ссылок, которые указывают на «myfolder»:

find ~/my-existing-links/ -lname '*/myfiles/*' -printf "%f\n" > results.txt

И я использую следующий cmd для обратного соответствия, т.е. для списка файлов в myfiles, которые не связаны с:

ls ~/myfiles | grep -vf results.txt > results2.txt

Итак, results2.txt содержит список файлов, для каждого из которых я теперь хочу создать новую символическую ссылку на.... в папке с именем ~/newlinks.

Я знаю, что можно передать 'ln -s' список файлов, используя комбинацию find/exec, т.е.

find ~/myfiles/ -exec ln -s {} -t ~/newlinks \; -print

.... но это будет нефильтрованный список файлов в myfiles. Я хочу использовать отфильтрованный список.

Любые идеи, как я могу это сделать? Я собираюсь регулярно добавлять файлы в myfiles и поэтому буду периодически посещать папку с целью создания символических ссылок для всех новых файлов, чтобы я мог логически разделить ссылки (а не менять исходное имя файла).


person Jim    schedule 07.06.2015    source источник


Ответы (4)


Попробуйте с xargs:

cat results2.txt | xargs -I{} ln -s {} ~/newlinks
person pasaba por aqui    schedule 07.06.2015

Вы можете использовать xargs для применения ссылок, чтобы ваш составной команда может выглядеть так:

find ~/myfiles/ | grep -vf results.txt | xargs make-my-links

а make-my-links будет примерно таким сценарием:

#!/bin/sh
for source in "$@"
do
    ln -s "$source" -t ~/newlinks
done

Отдельный сценарий и цикл используются с xargs, потому что он не принимает шаблон команды, но будет (по умолчанию) отправлять столько входных данных, сколько, по его мнению, поместится в командной строке.

person Thomas Dickey    schedule 07.06.2015

Итак, у вас есть 3 объекта типа каталог:

  • ~/myfiles/: содержит ваши файлы.
  • ~/my-existing-links/: содержит ссылки на файлы из ~/myfiles/.
  • ~/newlinks/: содержит ссылки на новые файлы от ~/myfiles/

Для меня третья сущность довольно ненужна. Почему новые ссылки не создаются прямо в ~/my-existing-links/?

Я бы использовал скрипт только для обновления списка ссылок в ~/my-existing-links/ всякий раз, когда в ~/myfiles/ добавляются новые файлы:

update_v1.sh

#!/bin/bash
for f in $(find ~/myfiles -type f); do
    ln -sf "$f" "~/my-existing-links/$(basename $f)"
done

update_v2.sh

find ~/myfiles -type f -exec sh -c \
     'for f; do ln -sf "$f" "~/my-existing-links/${f#*/}"; done' sh {} +

update_print.sh

#!/bin/bash
for f in $(find ~/myfiles -type f); do
    if [[ ! -L "~/my-existing-links/${f#*/}" ]]; then
        echo "Link not existing for $f"
    fi
done
person Eugeniu Rosca    schedule 07.06.2015
comment
Вместо того, чтобы проверять, существует ли перед созданием, ln -sf принудительно создать ссылку, независимо от того, существует она или нет. - person Cometsong; 07.06.2015
comment
Спасибо. Не пробовал, но выглядит лаконично. Причина, по которой я предпочитаю хранить новые ссылки в отдельной папке, заключается в том, что я хочу просмотреть их вручную, прежде чем помещать в соответствующую папку в основной папке «ссылки» и/или переименовывать и/или копировать ссылку по мере ее сохранения. . Но в любом случае, спасибо за ваш вклад. - person Jim; 08.06.2015
comment
@Jim: я по-прежнему считаю, что задача просмотра новых файлов может быть выполнена без третьего каталога ~/newlinks/. Я добавил пример update_print.sh для печати тех файлов, на которые нет ссылки, указывающей на них из ~/my-existing-links. - person Eugeniu Rosca; 08.06.2015

Спасибо, Томас и пасаба... Я нашел способ сделать это:

Поэтому я сделал следующее из ~/newlinks :

while read line; do ln -s "$line" "${line##*/}" ; done < ~/myfiles/results2.txt

Еще раз спасибо за ваше время.

person Jim    schedule 07.06.2015