Я копирую файлы из папки src в папку dest с помощью команды:
cp -nv /src/* /dest/ > copy_result.txt
Результат копирования файлов находится в выходном файле, как показано ниже:
« /src/test1.txt » -> « /dest/test1.txt »
« /src/test2.txt » -> « /dest/test2.txt »
В противном случае я хочу, чтобы выходной файл содержал только имя файла, без полного пути и без расширения файла, например так:
test1
test2
решение1
Попробуйте команду
cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
awk
печатает шестое поле. И rev
переворачивает строку. cut
разбивает строку по разделителю, указанному -d
, извлекает часть, указанную -f
.
Редактировать:
Как уже было сказано, это не дружит с файлами/каталогами с пробелами. Но это будет извлекать подстроки между '-> « ' и ' »' :
cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
решение2
-v
не специфицировано POSIX. Это означает, что каждая cp
реализация может обрабатывать его по-разному (или не обрабатывать вообще). Где ваш cp
говорит, « foo »
мой говорит 'foo'
. Можно создать команду, которая преобразует ваш нежелательный вывод в желаемый, но я все же хотел бы представить решение, независимое от cp
реализации.
После того , как /src/*
в вашей команде развернутся, cp
копирует полученные записи одну за другой. Это означает, что вы можете превратиться cp -n /src/* /dest/
в
for file in /src/*; do cp -n "$file" /dest/; done
Теперь легко что-то сделать с $file
. Это сгенерирует нужный вам вывод:
for path in /src/*; do
file="${path##*/}"
dst="/dest/$file"
[ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done
(Для перенаправления на copy_result.txt
использование done > copy_result.txt
вместо просто done
).
Обратите внимание, если вы использовали cp -r -v
и хотя бы один из операндов из расширения /src/*
был каталогом, cp
он скопировал бы и вывел бы его содержимое, в то время как приведенный выше код (после добавления -r
) скопировал бы столько же, но вывел бы только сам каталог. -r
может быть не единственным вариантом, который мог бы привести к расхождению.
Таким образом, хотя подход должен быть независимым от cp
реализации, он полагается на то, что некоторые опции не используются. Другим недостатком является то, что код запускает отдельный cp
процесс для каждого объекта в /src/
, это далеко от оптимального.
Также есть состояние гонки: если $dst
файл появляется между [
и cp
, cp
выполнит свою работу. Вы можете использовать cp -n
, чтобы избежать перезаписи, но printf
все равно сообщит о файле.