При использовании разделенных \ 0
строк, это может обрабатывать пробелов
и \ n
в именах файлов.
cd "${PROJECT_DIR%/*}"
outdir="output"; mkdir -p "$outdir"
find "$PROJECT_DIR" -type f -name '*.log' -printf "%p\0${outdir}/%P\0" |
awk 'BEGIN{FS="/";RS=ORS="\0"}
NR%2||NF==2 {print; next}
{gsub("/","#"); sub("#","/#"); print}' |
xargs -0 -n2 cp -T
mkdir -p
создает целевой каталог (без ошибок, если он уже существует). find
печатает \ 0
-удаленные пути к файлам (% P
означает без find
каталога $ 1
- дорожка). awk
создает 2 пути к файлам, требуемые для cp
, как две записи с разделителями \ 0
. xargs
считывает \ 0
-ограниченных путей к файлам, по 2 за раз, и передает их в cp -T
Вот дерево
из тестовый исходный каталог`
projectdir
├── file0.txt
├── file1.log
└── subdir
├── file2.log
└── subsubdir
└── file3.log
2 directories, 4 files
Вот дерево
целевой каталог`
output
├── file1.log
├── #subdir#file2.log
└── #subdir#subsubdir#file3.log
0 directories, 3 files
(cd "$ PROJECT_DIR" && find. -Name "* .log") | tar -cf - -T - | (cd $ OUTPUT_DIR && tar -xf -)
#!/bin/bash
newdir=/absolute/path/output
olddir=/absolute/path/project
find $olddir -name '*log' | while read line ; do
if [ "$olddir" == "$( basename "$line" )" ] ; then
#just move the file if there are no subdirectories
mv "$line" "$newdir"
else
#1) replace old project dir with nothing
#2) replace all slashes with hashes
#3) set new outdir as prefix
#4) hope that there are no colons in the filenames
prefix="$( sed -e "s:$olddir::" -e 's:/:#:g' -e "s:^:$newdir/:" <<<"$( dirname "$line")" )"
mv "$line" "$prefix"#"$( basename "$line" )"
fi
done