Как отобразить только имя файла в качестве вывода команды cp?

Как отобразить только имя файла в качестве вывода команды cp?

Я копирую файлы из папки 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все равно сообщит о файле.

Связанный контент