«одна строка», но sed
не будет работать для новых строк $'\n'
в имени файла
при условии, что вы cd
войдете в папку проекта и запустите find .
всегда с .
будет соответствовать targettring (на любом уровне) и скопирует все (содержащее) дерево из первого уровня
пример дерева
searchProjectFolder/some/parent/folders/matched/targetstring/foo/bar/
при поиске *targetstring*
внутри searchProjectFolder/
будет скопирована вся папка ./some
(включая все файлы и подпапки)
, а -regex
или -ipath
распечатает все файлы, -iname
распечатает только соответствующую папку targetstring/
. вы можете ограничить поиск указанными c уровнями с -mindepth 5
и -maxdepth 5
и указать целевой тип для соответствия папок только с -type d
(но давайте уберем эту опцию для сейчас)
создайте newProjectFolder и запустите find для дерева примеров
mkdir newProjectFolder
cd searchProjectFolder
find . -iname "*targetstring*"
результат для дерева примеров равен
./some/parent/folders/matched/targetstring
now find
результат передается в grep
, поэтому мы можем обрезать строку только до первого уровня
find . -iname "*targetstring*" | grep -o ^\./[^/]*
результат в примере дерева равен
./some
вместо grep
мы можем использовать sed
, чтобы заключить в кавычки "имя папки" (может иметь пробелы)
find . -iname "*targetstring*" | sed -n 's,^\(\./[^/]*\).*,"\1",p'
результат на примере дерева равен
"./some"
наконец, давайте cp
все папки с eval
, потому что "имена папок" заключены в кавычки. это «однострочник»:
eval cp -a $(find . -iname "*targetstring*" | sed -n 's,^\(\./[^/]*\).*,"\1",p') ../newProjectFolder
результат на примере дерева
cp -a "./some" ../newProjectFolder
для лучшего понимания я объясню sed
sed -n 's,^\(\./[^/]*\).*,"\1",p'
sed -n 's, ^ \( \. / [^/]* \) .* , "\1" ,p'
-n
= не печатать ввод
p in ,p'
= печатать только совпадающий вывод
\1
= печатать первую группу захвата
\(
= начало группы захвата
\)
= конец группы захвата
^
= совпадение начала только строки
\.
= одна точка (.
)
/
= одиночный sla sh (разделитель пути)
[^/]
= любой отдельный байт, но не sla * sh
[^/]*
= любая строка, не содержащая косую черту
.
= одиночный байт
.*
= любая строка
, поэтому (первая) группа захвата (начало строки)
./example string
группа захвата цитируется ("\1"
)
"./example string"
edit:
еще одна "настоящая" однострочная строка, если вы хотите скопировать папку targetstring/
(с родительским деревом)
mkdir newProjectFolder
cd searchProjectFolder
find . -iname "*targetstring*" -exec cp -a --parents {} ../newProjectFolder \;
результат в примере дерева:
cp -a --parents "./some/parent/folders/matched/targetstring" ../newProjectFolder