Копирование файлов в Linux
Копирование файлов — одна из задач, наиболее часто возникающих перед пользователями персонального компьютера. Конечно, можно открыть файловый менеджер, войти в нужную папку и скопировать файл с помощью контекстного меню — тут не о чем говорить. Но в этой статье я хотел бы рассмотреть копирование файлов в Linux с помощью терминала.
Не всегда есть доступ к файловому менеджеру: из-за различных поломок графическая оболочка на домашнем компьютере может быть недоступна, а на серверах используется только консольный интерфейс. К тому же копирование файлов Ubuntu через терминал намного эффективнее, и вы сами в этом убедитесь. Сегодня мы рассмотрим не только обычное копирование командой cp Linux, но и не совсем обычное: с помощью tar и find.
Содержание статьи:
Утилита копирования файлов cp
Название утилиты cp — это сокращение от Copy, что означает копировать. Утилита позволяет полностью копировать файлы и директории.
Синтаксис и опции
Общий синтаксис cp выглядит вот так:
$ cp опции файл-источник файл-приемник
Или:
$ cp опции файл-источник директория-приемник/
После выполнения команды файл-источник будет полностью перенесен в файл-приемник. Если в конце указан слэш, файл будет записан в заданную директорию с оригинальным именем.
Утилита имеет несколько интересных опций, которые могут сильно помочь при нестандартных задачах копирования, поэтому давайте их рассмотрим:
- —attributes-only — не копировать содержимое файла, а только флаги доступа и владельца;
-f, —force — перезаписывать существующие файлы;- -i, —interactive — спрашивать, нужно ли перезаписывать существующие файлы;
- -L — копировать не символические ссылки, а то, на что они указывают;
- -n — не перезаписывать существующие файлы;
- -P — не следовать символическим ссылкам;
- -r — копировать папку Linux рекурсивно;
- -s — не выполнять копирование файлов в Linux, а создавать символические ссылки;
- -u — скопировать файл, только если он был изменён;
- -x — не выходить за пределы этой файловой системы;
- -p — сохранять владельца, временные метки и флаги доступа при копировании;
- -t — считать файл-приемник директорией и копировать файл-источник в эту директорию.
Примеры копирования файлов в linux
Теперь, когда вы знаете основные опции, можно перейти к практике. Например, мы хотим скопировать некую картинку из домашней папки в подкаталог pictures:
cp ~/pic.png ~/pictures/
Или можем явно указать имя новой картинки:
cp ~/pic.png ~/pictures/wallpaper.png
Копирование папок осуществляется с помощью ключа -r:
cp -R ~/папка ~/Документы/
После выполнения этой команды копирования ~/папка будет скопирована в папку ~/Документы. Главное, не забывайте поставить слэш в конце выражения или использовать опцию
По умолчанию команда cp Linux перезаписывает существующие файлы или папки, но можно заставить утилиту спрашивать, нужно ли перезаписывать каждый файл, если вы не уверены в правильности составления команды:
cp -i ~/test ~/Documents/test
Есть и противоположная опция -n, означающая «никогда не перезаписывать существующие файлы».
Опция -u полезна в следующем случае: вы знаете или предполагаете, что в директории, куда копируется файл, есть старая его версия, тогда оператор -u выполнит замену на новую версию:
cp -u ~/test ~/Documents/test
Сp также поддерживает специальные символы замены * и ?. Например, следующая команда скопирует все файлы, начинающиеся на test:
cp ~/test* ~/Документы/
Если нужно применить более сложные регулярные выражения, придётся комбинировать утилиту cp с find или egrep.
В случае, если важно сохранить права доступа к файлу и его владельца, нужно использовать опцию -p:
cp -p ~/test* ~/Документы/
Для упрощения использования команды можно применять синтаксис фигурных скобок. Например, чтобы создать резервную копию файла, выполните:
$ cp test.conf{,.bak}
Будет создан файл с таким же именем и расширением .bak
По умолчанию в cp не отображается прогресс копирования файла, что очень неудобно при работе с большими файлами, но его можно легко посмотреть с помощью утилиты cv.
Копирование файлов по регулярным выражениям в Linux
В утилите find можно применять различные условия и регулярные выражения для поиска файлов. Я уже немного писал о ней в статье как найти новые файлы в Linux. Мы можем скопировать все найденные с помощью find файлы, вызвав для каждого из них команду
find . -name [0-9] -exec cp {} ~/Документы \
Здесь точка указывает на текущую директорию, а параметр name задает регулярное выражение. Параметром exec мы задаем, какую команду нужно выполнить для обнаруженных файлов. Символ {} — подставляет имя каждого файла.
Но не find‘ом единым такое делается. То же самое можно получить, запросив список файлов директории в ls, отфильтровав его по регулярному выражению egrep и передав имена файлов по очереди в
ls -1 ~/ | egrep '[a-zA-Z]' | xargs cp -t ~/Папка/
Это не совсем удобный способ копировать файлы Linux, но всё же он возможен. Будут скопированы все файлы из домашней директории, содержащие в имени только английские буквы.
Копирование содержимого файлов в Linux
Вы можете не только копировать сами файлы, но и управлять их содержимым. Например, склеить несколько файлов в один или разрезать файл на несколько частей. Утилита cat используется для вывода содержимого файла, в комбинации с операторами перенаправления вывода Bash вы можете выполнять копирование содержимого файла Linux в другой файл. Например:
cat файл1 > файл2
Если файл был не пустым, он будет перезаписан. Или мы можем склеить два отдельных файла в один:
cat файл1 файл2 > файл3
Специальное копирование файлов в Linux с помощью tar
Linux интересен тем, что позволяет выполнять одно и то же действие различными путями. Копирование в Linux тоже может быть выполнено не только с помощью cp. При переносе системных файлов в другой каталог, резервном копировании системных файлов и т.д. важно чтобы сохранились атрибуты, значения владельцев файлов и символические ссылки как они есть без какой-либо модификации.
Утилита cp тоже может справиться с такой задачей? если указать опцию -p
tar cf - /var | ( cd /mnt/var && tar xvf - )
Здесь мы полностью копируем содержимое папки /var в папку /mnt/var. Так вы можете копировать папку Linux, причём абсолютно любую или даже целую операционную систему.
Выводы
Теперь вы знаете, как выполняется копирование файлов Ubuntu и в Linux в целом. Как видите, в терминале это выполняется намного быстрее и эффективнее, чем с помощью графического интерфейса, если помнить нужные команды. Если у вас остались вопросы, спрашивайте в комментариях!
Оцените статью:
Загрузка…losst.ru
(OS X Shell) Копирование файлов на основе текстового файла, содержащего имена файлов без расширений — shell
Предисловие: Im не очень много shell-scripter, на самом деле не скриптовый скрипт вообще.
У меня есть папка (folder/files/
) со многими тысячами файлов в ней с разными расширениями и случайными именами. Ни одно из имен файлов не содержит пробелов. Вложенных папок нет.
У меня есть текстовый файл (filelist.txt
) с несколькими сотнями имен файлов, и все они без расширений. Все имена файлов имеют соответствующие файлы в
, но с различными расширениями. У некоторых может быть более одного соответствующего файла в folder/files/
с разными расширениями.
Пример из filelist.txt
:
WP_20160115_15_11_20_Pro
P1192685
100-1373
HPIM2836
Они могут, например, соответствовать следующим файлам в folder/files/
:
WP_20160115_15_11_20_Pro.xml
P1192685.jpeg
100-1373.php
100-1373.docx
HPIM2836.avi
(Обратите внимание на два файла с именем 100-1373
с разными расширениями.)
Я работаю над машиной OS X (10.11). Мне нужно сделать folder/files/
, которые соответствуют имени файла в filelist.txt
в folder/copiedfiles/
. 1
Ive искал и Googling как сумасшедший для немного сейчас, и Ive нашел bucketloads людей, объясняющих, как извлекать имена файлов без расширений, находить и копировать все файлы, у которых нет расширения, и различные касательные связанные проблемы, — но я не могу найти все, что действительно помогает мне выяснить, как это сделать в частности. Выполнение cp ˋcat filelist.txtˋ folder/copiedfiles/
будет работать (насколько я могу судить), если имена файлов в текстовом файле включали расширения; но они не делают, так оно не делает.
Каков самый простой (и желательно самый быстрый) способ сделать это?
1 То, что мне нужно сделать, точно такое же, как в этом вопросе, но этот вопрос конкретно спрашивает о batch-file, который представляет собой очень отличный чайник -dwellers.
qaru.site
Сценарий Bash Shell для копирования файлов из источника в пункт назначения
Вопрос:
У меня есть вопрос, связанный с моим скриптом оболочки bash. В принципе, мне нужно разработать скрипт, который копирует определенные файлы из одного каталога в другой. Звучит просто, но для меня это довольно сложная задача, и я надеюсь, что некоторые из вас могут мне помочь. Итак, скрипт должен работать следующим образом:
Имя_файла Source_path Destination_path
1) 1-я проблема. Возможно, путь source_path отсутствует, и мне нужно эхо-сообщение об ошибке.
2) Вторая проблема — путь назначения может не существовать, однако мне нужно создать некоторые или все каталоги, а затем скопировать файлы из источника. Иначе, если каталог существует, мне просто нужно скопировать.
Надеюсь, это ясно и, надеюсь, кто-то может мне помочь!
Лучший ответ:
Если вы хотите использовать команду find
, попробуйте следующее:
find SRCPATH -exec mkdir -p DSTPATH/$(dirname "{}") \; -exec cp --parents "{}" DSTPATH \;
Каждый флаг
-exec
блок кода оболочки для выполнения и\;
завершает его. Получение нескольких команд в одном-exec
оказалось для меня проблемой в прошлом, поэтому я включаю два, по одному для каждой задачи.{}
Являетсяfind
синтаксис для переменной, которая указывает путь токаfind
является пересекающий.Примечание. Флаг
--parents
относится к вариантуcp
Linux/GNU, но не доступен для всех версийcp
, поэтому нижеприведенный сценарий менее зависим от платформы. Кроме того, ваш вопрос касался использования скрипта.Примечание:
SRCPATH
иDSTPATH
представляют представляющие интерес пути. Если какое-либо имя каталога источника или адресата содержит пробелы, вам придется заключить их в" "
В качестве альтернативы вы можете создать скрипт bash
.
#!/bin/bash
srcpath=$1
dstpath=$2
if [ ! -d "$srcpath" ]; then
echo "Source path: $srcpath doesn't exist"
exit 1
fi
mkdir -p "$dstpath"
cp -r "$srcpath/*" "$dstpath"
Флаг
-d
в оператореif
является флагом для проверки наличия да/нет в каталоге. Здесь некоторая информация об операторе тестирования файла bash и других операциях сравнения bashФлаг
-p
на mkdir сообщает, что он должен заполнить недостающие компоненты пути по мере необходимости. Без-p
mkdir
ожидает, что каждый компонент пути, кроме конечной составляющей пути, будет присутствовать или он потерпит неудачу.Флаг
-r
в cp сообщаетcp
рекурсивно копировать все подкаталоги, а также файлы, обозначенные*
в пункт назначения, при необходимости создавая эти подкаталоги.Примечание. «» Вокруг путей — это защита от ошибок, если какой-либо из компонентов пути содержит пробелы.
Ответ №1
Посмотри на это:
find SOURCEPATH -type f | while read fname
do
mkdir -p TARGETPATH/$(dirname "$fname")
cp --parents $fname TARGETPATH
done
Просто подстановка SOURCEPATH и TARGETPATH, и вы хороши. find
будет отображать ошибку, если SOURCEPATH не существует (1), а mkdir -p
создаст каталоги.
Ответ №2
Этот скрипт создает всю структуру каталогов в $2
включая пустые папки от $1
:
#!/bin/sh
[ -z "$2" ] && { echo "Usage: $0 SOURCE DEST"; exit 1; }
[ ! -d "$1" ] && { echo "'$1' does not exist or isn't a directory"; exit 1; }
cp -r "$1" "$2"
Если пустые каталоги должны быть пропущены, вам потребуется еще немного логики; если rsync
не доступен:
#!/bin/sh
[ -z "$2" ] && { echo "Usage: $0 SOURCE DEST"; exit 1; }
[ ! -d "$1" ] && { echo "'$1' does not exist or isn't a directory"; exit 1; }
rsync -mr "$1" "$2"
Объяснение:
- Строка с
-z
проверяет, что второй аргумент не пуст - Линия с
! -d
! -d
проверяет, существует ли каталог из первого аргумента -
cp -r
копирует рекурсивно -
rsync -mr
копирует рекурсивно, но пропускает пустые каталоги -
&&
и||
широко используются подстановки для условных утверждений (потому что они короткие)
Ответ №3
Задайте переменные для аргументов один и два, источник и dest соответственно.
src_dir=$1
dest_dir=$2
Проверьте, существует ли каталог, если нет
[[ -d $src_dir ]] || { echo "source dir not exist"; exit 1 ; }
Создание всех путей, необходимых в пути
mkdir -p $dest_dir
techarks.ru
Как правильно скопировать файлы и папки исключая некоторые из них / Habr
Топик написан в ответ на похожий.Автор оригинального топика предлагает решить задачу в лоб — а именно, скопировать все файлы а потом удалить не нужные. Это может быть неплохим решением, если вам, конечно, не нужно скопировать всю домашнюю папку на флешку, за исключением вашей коллекции видео.
Но главная проблема этого подхода в другом — он не соответствует идеологии unix: сложные задачи решаются комбинацией простых утилит.
Под катом подробности о методах решения этого класса задач — не рассматривайте это как готовый рецепт.
0. Декомпозиция
Решение любой комплексной задачи начинается с разбора её на составные части. Итак нам нужно скопировать некоторый набор файлов предварительно его отфильтровав.
Значит — получение списка файлов, фильтрация, копирование.
1. Получение списка файлов
Обычно мы просматриваем список файлов программой ls. Её вывод выглядит примерно так:
$ ls -1
dir1
dir2
file1.bin
file2.txt
Подходит ли там такой вывод? Нет, потому, что в нем недостаточно информации — нам нужно копировать файлы рекурсивно, значит для нас было-бы гораздо удобнее если первая в нашей цепочке программа выдала там имена файлов вместе с путями.
Следующая программа, которая приходит на ум — find
$ find ./
./
./dir1
./dir1/file7.txt
./dir2
./file1.bin
./file2.txt
Уже лучше но в вывод попали и директории, а они нам не нужны. Попробуем так:
$ find ./ -type 'f'
./dir1/file7.txt
./file1.bin
./file2.txt
Вот то, что там нужно. Список файлов.
2. Фильтрация
Этот список файлов нужно отфильтровать. Перенаправим вывод нашей предыдущей комманды в программу grep.
$ find ./ -type 'f' | grep 2
./dir2
./file2.txt
Хорошо, но в условиях задачи стоит исключать файлы, так что немного поменеяем наш конвейер
$ find ./ -type 'f' | grep -v 2
./dir1/file7.txt
./file1.bin
Первые две части выполнены.
3. Копирование
Из man-страницы для команды cp мы можем узнать, что исходный файл нужно передавать программе cp в качестве аргумента, а мы пока можем только перенаправить список на стандартный ввод.
Применим утилиту xargs — она принимает стандартный ввод и вызывает указанную программу с параметрами из стандартного ввода. Итак:
$ find ./ -type 'f' | grep -v 2 | xargs -n 1 -I % cp --parents "%" /path/to/dest/dir/
-n 1 значит, что только одна строка из стандартного ввода подставляется в комманду, а -I % — определяет символ, который будет заменен в целевой комманде на строчку из стандартного ввода. В нашем случае это будет
cp --parents "./dir1/file7.txt" /path/to/dest/dir/
cp --parents "./file1.bin" /path/to/dest/dir/
Можно считать, что задача решена.
Вместо заключения
Я надеюсь что это описание поможет правильно подходить к решению как таких простых так и более комплексных задач.
Хочется отметить, что
- Это топик способах решения задач и немного о применении конвейера, а не о копировании файлов
- Этот способ далеко не едиственный и даже не самый короткий, а наиболее наглядный для демонстрации методологии решения.
- В случае этой конкретной задачи будет быстрее воспользоваться
find ./ -type f ! -name "*2*" -exec cp --parents -t /target/dir "{}" \+
- Лично я воспользовался-бы
tar --exclude=2 -cf - ./ | ( cd /path/to/dest/ && tar -xvf - )
- Т.к. это первый мой топик, буду рад конструктивной критике
habr.com
Shell Script скопировать и вставить случайный файл из каталога — bash
В этой демонстрации script показано, как вы можете выбрать случайный файл из каталога и должно быть хорошим началом.
#!/bin/bash
# Set up test data.
rm -rf tmpdata ; mkdir tmpdata
touch tmpdata/fileA tmpdata/fileB tmpdata/fileC tmpdata/fileD tmpdata/fileE
# From and To directories
fromdir=./tmpdata
todir=./tmpdata2
# Get a list of the files to a temporary file.
ls -1 ${fromdir} >/tmp/filelist.$$
# Select a number from 1 to n where n is the line count of that file.
# Then use head and tail to get the line.
filenum=$(expr $RANDOM % $(cat /tmp/filelist.$$ | wc -l) + 1)
file=$(head -${filenum} /tmp/filelist.$$ | tail -1)
# DEBUG stuff.
cat /tmp/filelist.$$ | sed 's/^/DEBUG file: /'
echo "DEBUG nmbr: ${filenum}"
echo "'cp ${fromdir}/${file} ${todir}'"
# Remove temporary file.
rm -f /tmp/filelist.$$
И некоторые выходные данные:
pax$ ./cprnd.sh
DEBUG file: fileA
DEBUG file: fileB
DEBUG file: fileC
DEBUG file: fileD
DEBUG file: fileE
DEBUG nmbr: 3
'cp ./tmpdata/fileC ./tmpdata2'
pax$ ./cprnd.sh
DEBUG file: fileA
DEBUG file: fileB
DEBUG file: fileC
DEBUG file: fileD
DEBUG file: fileE
DEBUG nmbr: 1
'cp ./tmpdata/fileA ./tmpdata2'
pax$ ./cprnd.sh
DEBUG file: fileA
DEBUG file: fileB
DEBUG file: fileC
DEBUG file: fileD
DEBUG file: fileE
DEBUG nmbr: 5
'cp ./tmpdata/fileE ./tmpdata2'
«Магия» лежит в этих двух строках:
filenum=$(expr $RANDOM % $(cat /tmp/filelist.$$ | wc -l) + 1)
file=$(head -${filenum} /tmp/filelist.$$ | tail -1)
Первый использует wc
, чтобы получить количество строк (количество файлов). Затем он дает вам остаток при делении случайного числа на это значение, чтобы вы получили 0..n-1
и, добавив 1, вы получите 1..n
. Предположим, что это дает вам 10 для файла с пятью строками.
В следующей строке используется head
для получения первых десяти строк, а затем через tail
, чтобы получить последнюю строку этого набора (т.е. десятую строку из файла).
qaru.site
shell script копировать из одного файла и вставлять другой файл — xml
Я хочу скопировать некоторые строки из одного файла и вставить его в другой файл в определенном месте, используя сценарий оболочки
Например: я хочу скопировать строки со строкой "name2"
и "inst"
в строке и заканчивая строкой </inst>
после строки name2
из file1.xml
в file2.xml
.
Место для вставки строк в файл2.xml — это строка, содержащая текст «clipKTP».
file1.xml
<Manufacturer clause >
<inst abtz "nameABC"> //Inst nameABC
<pressure 100> </pressure>
<temp 50> </temp>
</inst>
<inst abtz "name2"> //Inst name2
<pressure 100> </pressure>
<temp 50> </temp>
</inst>
<inst abtz "name5678"> //Inst name5678
<pressure 100> </pressure>
<temp 50> </temp>
</inst>
</Manufacturer>
file2.xml
<Measure> atk
<inst abtz "name1"> // Inst name1
<pressure 100></pressure>
<temp 50></temp>
</inst>
<clipton> "clipKTP"
<slave slvgo > </slave>
</clipton>
</Measure>
Результат file2.xml
должен выглядеть так:
<Measure> atk
<inst abtz "name1"> // Inst name1
<pressure 100></pressure>
<temp 50></temp>
</inst>
<inst abtz "name2"> //Inst name2
<pressure 100></pressure>
<temp 50></temp>
</inst>
<clipton "clipKTP">
<slave slvgo > </slave>
</clipton>
</Measure>
источник
поделитьсяqaru.site
Cкрипт копирования файлов по сети
Копировать большое количество файлов с компьютера на компьютер по локальной сети — дело долгое и однообразное, и после первого часа такой рутинной работы она становится просто невыносимой и хочется, наконец, её автоматизировать. В этом может помочь простейший скрипт копирования файлов по сети, который и будет выполнять большинство действий за вас.
Ниже будет представлены 2 скрипта, использующие «язык VBS», для элементарного перемещения файла из одной сетевой папки, (она конечно же, должна быть «расшарена») в другую.
vbs скрипт копирования файлов по локальной сети
- Данный скрипт подойдет для поштучного перемещения файлов из одной папки в другую:
WScript.Echo «Готово.» # данные строки выводят текстовое уведомление/сообщение
WScript.Quit(0)
Dim fso
Set fso = CreateObject(«Scripting.FileSystemObject»)
fso.CopyFile «\\1-4ffc2e2aa3494\1\Рабочий стол\Test\1.vbs «, # в данной строке указывается адрес папки, из которой будет производиться копирование
«C:\Documents and Settings\Администратор\Рабочий стол\Test» #адрес папке куда будет копироваться файл.
Скрипт копирования файлов и папок по сети
- Для того чтобы скопировать всё содержимое папки используется следующий скрипт:
WScript.Echo «Готово.»
WScript.Quit(0)
Const OverWriteFiles = True # три нижние строки определяют параметры копирование всех файлов в из папки
Set objFSO = CreateObject(«Scripting.FileSystemObject»)
objFSO.CopyFolder «\\1-4ffc2e2aa3494\1\Рабочий стол\Test» ,
» C:\Documents and Settings\Администратор\Рабочий стол\Test \» , OverWriteFiles
Как видите, скрипт наилегчайший. Вам останется только создать текстовый документ, скопировать код и изменить его адреса в соответствии с вашей сетью (а именно те строки, где находятся адреса откуда и куда нужно скопировать файлы). После этого требуется сохранить скрипт с английской раскладкой и разрешением «.vbs».
Если копируемые файла требуется обновлять постоянно, можно полностью автоматизировать данный процесс, создав в «Планировщике задач» сценарий и выставить в параметрах временные интервалы.
Данные скрипты являются одними из самых элементарных. Можно воспользоваться «Командной строкой» и командной «xcopy /?».
После запуска команды вы можете выбрать те параметры, которые вам необходимы, и после этого создать собственный скрипт.
tvoi-setevichok.ru