Копирование файлов в нескольких подкаталогах в командной строке Linux - PullRequest
2 голосов
/ 07 июля 2011

Допустим, у меня есть следующие подкаталоги

./a/, ./b/, ./c/, ... 

То есть в моем текущем рабочем каталоге находятся эти подкаталоги a/, b/ и c/, а в каждом из этих подкаталогов находятся файлы,В каталоге a/ находится файл a.in, в каталоге b/ находится файл b.in и т. Д.

Теперь я хочу скопировать каждый файл .in в файл .out,то есть с a.in до a.out и b.in до b.out, и я хочу, чтобы они находились в каталогах, из которых они были скопированы.Так что a.out будет найдено в каталоге a/.

Я пробовал различные подходы, такие как

find ./ -name '*.in'|cp * *.out

, который не работает, потому что он считает, что *.outкаталог.Также попытался

ls -d */ | cd; cp *.in *.out

, но он бы перечислял подкаталоги, входил в каждый из них, но не позволял бы cp делать свою работу (которая все еще не работает)

Команда

find ./ -name '*.in'

работает нормально.Есть ли способ передать аргументы в оператор присваивания?Например,

find ./ -name '*.in'| assign filename=|cp filename filename.out

, где assign filename= дает имени файла значение каждого .in файла.На самом деле, было бы еще лучше, если бы назначение могло избавиться от расширения файла .in, тогда вместо получения a.in.out мы бы получили предпочтительный a.out

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

Ответы [ 3 ]

4 голосов
/ 07 июля 2011

Пусть оболочка поможет вам:

find . -name '*.in' | while read old; do
    new=${old%.in}.out # strips the .in and adds .out
    cp "$old" "$new"
done

Я просто взял команду поиска, которая, как вы сказали, работает, и позволил bash прочитать ее вывод по одному имени за раз. Таким образом, цикл bash while получает имена файлов по одному, выполняет небольшую замену и прямую копию. Красиво и легко (но не проверено!).

1 голос
/ 07 июля 2011

Попробуйте цикл for:

for f in */*.in; do
    cp $f ${f%.in}.out;
done

Глобус должен перехватывать все файлы в одном каталоге с расширением .in. В команде cp он удаляет суффикс .in, а затем добавляет .out (см. Изменение переменных в Bash с помощью строковых операторов )

В качестве альтернативы, если вы хотите вернуться в каждый подкаталог (не только на 1 уровень глубины), замените глобус находкой:

for f in $(find . -name '*.in'); do
    cp $f ${f%.in}.out;
done
0 голосов
/ 07 июля 2011

Это должно сработать!

for f in `find . -type f -name "*.in"`; do cp $f `echo $f | sed 's/in$/out/g'`; done
...