2013-10-24 1 views
1

Я пытаюсь изменить thoughtbot's bash script на symlink dotfiles в домашний каталог, но я хочу сохранить свои файлы в подкаталоге.Как перебрать набор файлов в подкаталог и работать с ними

Оригинал из сценария thoughtbot является:

#!/bin/sh 

for name in *; do 
    target="$HOME/.$name" 
    if [ -e "$target" ]; then 
    if [ ! -L "$target" ]; then 
     echo "WARNING: $target exists but is not a symlink." 
    fi 
    else 
    echo "Creating $target" 
    ln -s "$PWD/$name" "$target" 
    fi 
done 

Мои в точечных файлов подкаталоге files. Я попробовал изменить петлю for на:

for name in files/*, for name in ./files/*, for name in 'files/*' и т. Д., Но ничего из этого не сработало.

После небольшого исследования, я вижу, что вы можете перебрать файлы в подкаталогах, используя find так:

find ./files -type f -exec "do stuff here" \; 

И я вижу, что я могу получить ссылку на каждый файл с '{}', но я не» я понимаю, как я могу работать с файлом и создавать символическую ссылку.

Я пробовал:

find ./files -type f -exec "ln -s '{}' $HOME/'{}'" \; 

, но это не работает, потому что '{}' относительный путь к файлу из родительского каталога, а не только имя файла.

Каков правильный способ сделать это?

Для справки, это то, что моя структура каталогов выглядит следующим образом:

https://github.com/mehulkar/dotfiles

+0

Используйте '-execdir' вместо' -exec'; первый выполняет команду в каталоге, который содержит соответствующий файл, а не каталог, в котором вы сейчас находитесь (т. е. {} будет содержать только имя файла, а не его полный путь относительно вашего CWD) – iscfrc

ответ

1

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

shopt -s dotglob 

Высказывание

for file in * 

не соответствует именам файлов, начиная с точки по умолчанию.

+0

Это отлично работало , Я также нашел [этот ответ] (http://stackoverflow.com/a/7477615/986415), чтобы просмотреть результаты поиска 'find files -type f'. Как теперь отрезать часть 'files /' на выходе? – mehulkar

+0

@MehulKar Вы можете использовать 'basename'. Выражение 'filename = $ (basename" $ ​​name ")' будет хранить имя файла без имени каталога, то есть 'files /' part, в переменной 'filename'. – devnull

+0

Спасибо, я закончил с помощью [string manipulation] (https://github.com/mehulkar/dotfiles/blob/master/install.sh#L7), но также работает basename. – mehulkar

0

... , но это не работает, потому что «{}» относительный путь к файлу из родительского каталога, а не только имя файла.

Попробуйте

find `pwd`/files -type f -exec "ln -s '{}' $HOME/'{}'" \; 

или

find $(pwd)/files -type f -exec "ln -s '{}' $HOME/'{}'" \; 

 Смежные вопросы

  • Нет связанных вопросов^_^