Ошибка cp в скрипте

Вы можете загрузить драйверы для MFC 240 C с веб-сайта братьев, но если вы ищете программное обеспечение PaperPort 12, поставляемое с оригинальным диском, теперь они хотят вас зарядить.

Похоже, вы не можете сканировать документ и открывать его без слов. Вам нужны они, чтобы сделать работу OCR, которая сделает это за вас. Я не мог найти программное обеспечение PaperPort 12 в любом месте бесплатно.

Вам действительно нужен этот оригинальный диск.

1
задан 31 August 2016 в 21:02

2 ответа

Одна из основных ошибок заключается в том, что вы пытаетесь использовать команду ls, но переменная LIST содержит только строку 'ls'. Вы можете использовать подстановку команд с синтаксисом $(command). В этом случае я бы посоветовал это сделать, поскольку он не даст вам информацию в том формате, который вы можете легко использовать. [* D0]

. В этом случае вы должны использовать сопоставление шаблонов оболочки, также известное как ошибка для синтаксического анализа вывода ls [!d1 ].

Вместо этого я предлагаю следующий метод в вашем скрипте:

#!/bin/bash
#make copies of all files in directory
for i in /home/don/* ; do
  if [[ -f $i ]]; then
    orig="$i"
    dest="${i}.old"
    cp "$orig" "$dest"
    echo "Copied $i"
  else
    echo "${i} is not a file"
  fi 
done
Это использует скопление оболочки для соответствия всем файлам в каталоге. ./* означает все в текущем каталоге (.). Оператор if проверяет, является ли совпадение файлом (не работает каталоги и ссылки), и выполняет ли ваша последовательность копирования, если это так. Я изменил имена переменных как строчные, так как переменные системной среды - это верхний регистр, поэтому вы избежите любых нежелательных конфликтов имен.
9
ответ дан 23 May 2018 в 06:36
  • 1
    Я изменил $ 1 на $ i в строке 5 вашего скрипта, и он отлично работает. Спасибо. – Don 31 August 2016 в 19:11
  • 2
    На всякий случай имена файлов имеют пробелы в них, переменную $ i следует указывать для предотвращения разделения слов. В противном случае, хорошая работа Arronical – Sergiy Kolodyazhnyy 31 August 2016 в 20:59
  • 3
    Кроме того, cd здесь необязательно, просто укажите полный путь, например ./home/don/* – Sergiy Kolodyazhnyy 31 August 2016 в 21:03
  • 4
    Спасибо @Serg, я сохранил cd там, чтобы более точно повторить исходный сценарий OPs, но соглашаюсь с тем, что использование абсолютного пути предпочтительнее. – Arronical 1 September 2016 в 11:22
  • 5
    Не запрашивается OP, но, с обычным значением ".old" можно было бы cp -p сохранить атрибуты файлов. (Если нет, то «старый» будет более новым, чем не старым.) – David Andersson 8 September 2016 в 23:30

Команда «find» vesion

Ваш скрипт может быть выполнен как команда с одним слоем find, без необходимости синтаксического анализа ls или возиться с глобусами и т. д.

Ваша цель, по мнению читателя, состоит в том, чтобы сделать копии всех файлов в текущем каталоге. Для этого подходящей командой будет:

find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;

Что это значит, что find работает со всеми файлами в каталоге . (текущий) и вызывает cp для каждого файла (следовательно [ f13]). Поскольку find является рекурсивным, мы должны ограничить глубину поиска, поэтому флаг -maxdepth и -mindepth должен избегать перечисления . в качестве одного из результатов поиска.

Пример прогона:

$ touch "file one"  "file two"                                                 
$ find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;                       
$ ls -1                                                                        
file one
file one.old
file two
file two.old
$ 

ПРИМЕЧАНИЕ. cp все равно будет жаловаться на каталоги. Есть несколько способов справиться с этим.

1) вы можете отфильтровать только файлы, если это ваша цель с флагом -type f в find, подобным

find . -mindepth 1 -maxdepth 1 -type f -exec cp {} {}".old" \;

2) Используйте cp -r для создания копий каталогов а также

find . -mindepth 1 -maxdepth 1 -exec cp -r {} {}".old" \;

Однострочный Python

Это немного длиннее, чем find, но все же выполняет задание и не имеет проблем со специальными именами файлов.

python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") for f in os.listdir(".") if os.path.isfile("./" + f)]'

Пример прогона:

$ touch "test file 1" "testfile 2"
$ python -c 'import shutil;import os;[shutil.copyfile(f,f + ".old")
> for f in os.listdir(".")
> if os.path.isfile("./" + f)]'
$ ls -1  
test file 1
test file 1.old
testfile 2
testfile 2.old
$ 

Чтобы включить каталоги, используйте shutil.copytree(source,destination)

python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") if os.path.isfile("./" + f) else shutil.copytree(f,f + ".old") for f in os.listdir(".")]'

Обратите внимание, что это не удастся, если вы скажете directory_one.old/ уже существует

2
ответ дан 23 May 2018 в 06:36
  • 1
    +1 для альтернативных методов, будет ли версия поиска просто жаловаться на отсутствие -r в команде cp, если она встречается с каталогом? – Arronical 8 September 2016 в 11:22
  • 2
    Когда вы сталкиваетесь с каталогом, моя система говорит cp: omitting directory 'dir1'. Можно добавить опцию поиска -type f. Тогда решение find будет соответствовать функциональности как решения python, так и решения bash Arronical в другом ответе. – David Andersson 8 September 2016 в 23:22
  • 3
    @Arronical Нет, версия find все равно будет жаловаться на отсутствие -r в cp, поэтому вы можете добавить его. По сути, это -exec вызывает sh -c . (На самом деле это системный вызов exec на программном уровне C, но для всех практических целей подумайте об этом как sh -c). – Sergiy Kolodyazhnyy 9 September 2016 в 00:43
  • 4
    @DavidAndersson Я обновил свой ответ, включив в него каталоги – Sergiy Kolodyazhnyy 9 September 2016 в 00:57

Другие вопросы по тегам:

Похожие вопросы: