Здравствуйте, я пытаюсь переместить все файлы с .hi и .o из целевой папки /src в другую папку /Obj

Пока что я попробовал:

    srcpath=$(pwd)"/src"

    ghc src/Main.hs > Logs/output.txt 2> Logs/Err.txt //this builds the project and generates the binaries and .hi files

    mv  *.hi *.o  $srcpath/src/ Obj/     //i want to move all these files to Obj/ folder but where do i place the extension arguments? 

Какой должна быть команда: mv extensions source dest ? или mv source dest extensions

Я пытался:

srcpath=$(pwd)"/src"
objpath=$(pwd)"/Obj"

ghc src/Company.hs > Logs/output.txt 2> Logs/Err.txt

mv *.o *.hi  $srcpath  $objpath

И я получаю следующую ошибку:

    mv: cannot stat '*.o': No such file or directory
mv: cannot stat '*.hi': No such file or directory
mv: cannot move '/c/Users/[..]/src' to '/c/Users/[...]/Obj/src': Device or resource busy

2 ответа2

2

С помощью команды mv *.o *.hi $srcpath $objpath вы перемещаете каждый файл с * .o или * .hi, а также папку src из текущей папки $(pwd) в Obj.

Если вы хотите переместить все * .o и * .hi, которые находятся в папке src , вы можете использовать это:

#!/bin/bash
srcpath=$(pwd)"/src"
objpath=$(pwd)"/Obj"

mv $srcpath/*.o $srcpath/*.hi  $objpath

Убедитесь, что ваш bash-скрипт работает в правильной папке, поэтому команда $(pwd) работает правильно.

Редактировать:

Если вы хотите переместить коллекцию файлов или файлов с определенным расширением, вы можете изменить скрипт так, чтобы он выглядел так (спасибо https://stackoverflow.com/a/8880633/7311363):

#!/bin/bash

srcpath=$(pwd)"/src"
objpath=$(pwd)"/Obj"

##declare an array variable
declare -a arr=("*.o" "*.hi")

##loop trough the array to move
for i in "${arr[@]}"
do
    mv $srcpath/$i $objpath
done
2

Похоже, вы рассматриваете *.o и *.hi как какие-то фильтры, используемые mv . Это не так, как это работает. Инструмент ожидает пути. Ваша оболочка может расширять *.o и *.hi до всех подходящих локальных путей из текущего каталога; если бы это сработало, mv увидит пути, а не шаблоны. Очевидно, у вас нет подходящих файлов, поэтому эти шаблоны не раскрываются и получают mv как есть, следовательно

mv: cannot stat '*.o': No such file or directory

и т.п.

Этот синтаксис может работать:

mv ./src/*.o ./src/*.hi ./obj/

Тем не менее, он (в некоторой степени) потерпит неудачу, если в ./src нет подходящих файлов. Вы можете ввести переменные, как вы это сделали, но

  • вам, вероятно, не нужен $(pwd) , достаточно srcpath="./src" ;
  • как правило, вы должны указывать свои переменные (но не шаблоны), например:

    mv "$srcpath"/*.o "$srcpath"/*.hi "$objpath"
    

Если файлов слишком много, вы попадете в argument list too long .


Это альтернативное решение с использованием find должно работать с большим количеством файлов или вообще без файлов:

find "$srcpath" -name "*.o" -o -name "*.hi" -exec mv {} "$objpath" \;

Смотри man 1 find чтобы узнать, как работает -exec . Также обратите внимание, что благодаря кавычкам строки типа "*.o" здесь не раскрываются оболочкой; find получает их буквально и использует встроенную процедуру сопоставления с образцом.

Решение будет запускать отдельную mv для каждого файла. Мы можем передать много аргументов в mv благодаря синтаксису find … -exec … {} + , но поскольку синтаксис требует, чтобы эти аргументы были в самом конце, нам нужно, чтобы mv поддерживал -t (это не требуется для POSIX, поэтому ваш mv может или не может поддержать это):

find "$srcpath" -name "*.o" -o -name "*.hi" -exec mv -t "$objpath" {} +

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .