2012-05-15 2 views
1
  • У меня есть каталог с 4-мя каталогами в нем.
  • Я хочу сделать 5-й каталог (cx1_date) и создать 4 пустых каталога с теми же именами, что и у исходного каталога
  • Затем я хочу скопировать два файла из каждого из исходных каталогов в новые подкаталоги с их соответствующие имена
  • Я думаю, что получаю сообщение об ошибке, потому что он пытается скопировать сам PWD (поскольку это отображается в результате вызова find), поэтому я попытался включить оператор if, но я думаю, т работаBash beginner: Ошибка при попытке скопировать каталог при создании подкаталогов

    now=$(date +"%m_%d_%Y") 
    
    PWD="/nmr/charlie" 
    
    mkdir $PWD/cx1_$now 
    
    for name in $(find $PWD -maxdepth 1 -type d); do 
    if [[ "$name" = "$PWD" && "$PWD" = "$name" ]]; 
    then 
        : 
    else 
        cd $PWD/cx1_$now 
        mkdir $PWD/$name 
        cd $PWD/$name 
        cp file1.ext $PWD/cx1_$now/$name 
        cp file2.ext $PWD/cx1_$now/$name 
    fi 
    done 
    

Первая строка ошибки

MkDir: невозможно создать каталог `/ мр/чарли/cx1_05_15_2012 // мр/ЧАРЛИ/cx1_05_15_2012' : Нет такого файла или каталога

Заранее благодарю за любую помощь вы можете дать !

Чарли

+0

Включите ошибку в вопросе – keyser

+0

вы можете отлаживать скрипт вставляя 'установить -vx' в верхней части сценария. (Ниже приведены ответы, чтобы решить проблему). Удачи. – shellter

ответ

2

Второй mkdir не хочет $PWD:

now=$(date +"%m_%d_%Y") 

DIR="/nmr/charlie" 

mkdir $DIR/cx1_$now 

for name in $(find $DIR -maxdepth 1 -type d) 
do 
    if [[ "$name" != "$DIR" ]] 
    then 
     (cd $DIR/cx1_$now; mkdir $name) 
     (cd $DIR/$name 
     cp file1.ext $DIR/cx1_$now/$name 
     cp file2.ext $DIR/cx1_$now/$name 
     ) 
    fi 
done 

Кроме того, PWD является встроенной переменной; вы не должны устанавливать его (за исключением команды cd).

Вам не нужен симметричный тест в if; вы можете использовать != вместо =, чтобы избежать пустого предложения then (хорошо, он содержит приятный анонимный код :, он вам не нужен, если вы инвертируете тест).

Я обычно кладу cd операции в подклассы; таким образом, я становлюсь менее смущенным. Альтернатива для второй линии mkdir это, что не нуждается в cd или подоболочке:

mkdir -p $DIR/cx1_$now/$name 

Я рекомендую использовать формат ISO 8601 для дат, такие как:

now=$(date +"%Y_%m_%d") 

Таким образом, каталоги сортируются в порядке дат автоматически.


I still get the error:

mkdir: cannot create directory `/nmr/charlie/directory_name_1': File exists 
/home/charlie/Desktop/scripts/test.sh: line 16: cd: /nmr/charlie//nmr/charlie/directory_name_1: No such file or directory 

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

... И мы должны использовать базовое имя каталога, и мы можем избежать всех cd операций тоже:

now=$(date +"%m_%d_%Y") 

DIR="/nmr/charlie" 

mkdir $DIR/cx1_$now 

for name in $(find $DIR -maxdepth 1 -type d | grep -v '/cx1_[^/]*$') 
do 
    if [[ "$name" != "$DIR" ]] 
    then 
     targetdir=$DIR/cx1_$now/$(basename $name) 
     mkdir -p $targetdir 
     cp $name/file1.ext $name/file2.ext $targetdir 
    fi 
done 

Вы знаете об использовании «ш -х script.sh» или ' bash -x script.sh ', чтобы запустить скрипт и посмотреть, что он делает.Я даже не уверен, что нам нужно условие if с grep, отфильтровывающее все, что похоже на каталог резервного копирования из списка.

Отмечу, что это работает только в том случае, если пути к каталогам являются нормальными и не содержат пробелов. Дела идут не так быстро, если вы используете непереносимые имена файлов (где переносные имена используют только [-_.A-Za-z0-9]). Новые линии и пространства действительно создают беспорядок.

Обратите внимание, что это было бы проще, если вы сделали резервную копию в каталогах под /nmr/backup/charlie или в любом другом месте, кроме /nmr/charlie. Однако, с осторожностью, это может быть сделано in situ по запросу.

+0

Спасибо за помощь, полезные советы, но я до сих пор получаю сообщение об ошибке: mkdir: невозможно создать каталог '/ nmr/charlie/имя_каталога_1 ': файл существует /home/charlie/Desktop/scripts/test.sh: строка 16 : cd:/nmr/charlie // nmr/charlie/directory_name_1: Нет такого файла или каталога – cc211

+0

круто, поэтому я теперь использовал bash-x, чтобы посмотреть, что он делает, я подумал, что он устранен без фактического выполнения скрипта, но я просто перезаписал много моих данных, используя его! Немного ошибки там с моей стороны. В любом случае вы можете сделать это консервативно, чтобы вы могли видеть, что он делает, не принимая на самом деле все действия cp rm и т. Д.? – cc211

+1

Есть несколько трюков. В то время как вы получаете синтаксис правильно, 'sh -nv script' может помочь. «-n» означает «no execute», а «-v» означает «verbose». Как только вы начнете тестирование, убедитесь, что вы проверили копию своих реальных данных, пока не убедитесь, что они ведут себя. Это вдвойне важно, если ваш скрипт может нанести ущерб (удалив файлы или необратимо изменив их). Еще одна вещь, которую я делаю, - это поставить «эхо» перед любыми опасными командами, пока я не рад, что они верны; это показывает мне (более или менее) то, что было бы выполнено без фактического выполнения. В противном случае держите хорошие резервные копии! –

2

Вы используете $ PWD, как будто это означает «/ nmr/charlie» и «/ nmr/charlie/cx1_date». Это означает только первый.

Кроме того, при прокрутке папок внутри вашего $ PWD он также будет содержать cx1_date, потому что вы уже создали его, поэтому вы должны это проверить.

И я бы не рекомендовал использовать PWD в качестве имени переменной, потому что он может использоваться для других целей.

[EDIT] Кроме того, $ name получает полный путь к каталогу, поэтому вам нужно использовать basename для получения только имени каталога без полного пути. Кроме того, я допустил ошибку в строке if, и она должна была быть! = Вместо = во втором сравнении. Извините, у меня не было оболочки в то время, чтобы проверить. Ниже приведен код ниже, я его протестировал.

Это должно работать:

now=$(date +"%m_%d_%Y") 

DIR="/nmr/charlie" 

mkdir $DIR/cx1_$now 

for name in $(find $DIR -maxdepth 1 -type d) 
do 
    if [[ "$name" != "$DIR" && "$name" != "$DIR/cx1_$now" ]]; 
    then 
     targetdir=$(basename $name) 
     cd $DIR/cx1_$now 
     mkdir $DIR/cx1_$now/$targetdir 
     cd $DIR/$targetdir 
     cp file1.ext $DIR/cx1_$now/$targetdir 
     cp file2.ext $DIR/cx1_$now/$targetdir 
    fi 
done 
+0

Я получаю следующую ошибку? Я все еще не могу понять, почему его удваивает. 0html/home/charlie/Desktop/scripts/test.sh: строка 17: cd:/nmr/charlie // nmr/charlie/cx1_2012_05_15: Нет такого файла или каталога – cc211

+0

Благодарим за помощь – cc211

+0

См. Мое редактирование, код в настоящее время работает. – Ceottaki

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