LINUX.ORG.RU

Скопировать все файлы, кроме одной директории

 , ,


0

1

Подскажите немного со скриптом. Допустим, на входе я получаю путь /tmp/taskdir/outputpath Скрипт должен скопировать все файлы из /tmp и положить их в outputpath. Загвоздка в том, как cp сказать, что taskdir копировать не надо, а остальное надо. Пробовал вот так, но пока не совсем то:

find /tmp ! -name $OMITDIR -print -exec cp -t "$OUTPUTDIR" {} +
Вторая проблема в том, как получить $OMITDIR.

★★★★★
Ответ на: комментарий от targitaj

rsync'a нет.. пока не знаю, имеет ли смысл его ставить.

UVV ★★★★★
() автор топика

grep, xargs

$ find /tmp | grep -v '/taskdir' | xargs -I '{}' cp '{}' $outputpath

Не пробовал, но как-то так.
Хорошенько отдебаж, особенно кусок с grep.

Kroz ★★★★★
()
find /tmp

Вторая проблема в том, как получить $OMITDIR.

А третья, как указывается /tmp. Если /tmp не переменная величина, то её указание в пути, который получает скрипт, избыточно, а, значит, может привести к сюрпризу.

gag ★★★★★
()
Последнее исправление: gag (всего исправлений: 1)
Ответ на: комментарий от UVV

А так

tmp=${to#$from/}
cp -r $from/!(${tmp%%/*}) $to
? Из пути назначения вырезается исходный путь, а после - концовка пути.

backbone ★★★★★
()
Последнее исправление: backbone (всего исправлений: 2)

намекаю вариант:

[sanja@phoenix test]$ tree && ls -1
.

0 directories, 0 files
[sanja@phoenix test]$ mkdir 1 2 3 4 5 1/1 1/1/1
[sanja@phoenix test]$ touch 2/02 3/03 4/04 5/05
[sanja@phoenix test]$ tree
.
├── 1
│   └── 1
│       └── 1
├── 2
│   └── 02
├── 3
│   └── 03
├── 4
│   └── 04
└── 5
    └── 05

7 directories, 4 files
[sanja@phoenix test]$ cp -r `ls -1|grep -v 1` 1/1/1/
[sanja@phoenix test]$ tree
.
├── 1
│   └── 1
│       └── 1
│           ├── 2
│           │   └── 02
│           ├── 3
│           │   └── 03
│           ├── 4
│           │   └── 04
│           └── 5
│               └── 05
├── 2
│   └── 02
├── 3
│   └── 03
├── 4
│   └── 04
└── 5
    └── 05

11 directories, 8 files

novitchok ★★★★★
()
Ответ на: комментарий от UVV

Потому что нечитаемо, потому что легко ошибиться, потому что рискуешь всю жизнь икать если твое творение придется использовать кому-то еще.
Посоветованный выше tar --exclude куда лучше.

Deleted
()

В zsh я бы так сделал:

cd /tmp
cp -r ^taskdir taskdir/outputpath

anonymous
()
Ответ на: комментарий от gag

Короче спасибо всем за наводки, я вот к чему пришёл, можете поругать:

# Omit output path because it's most likely in /tmp
SAVEIFS=$IFS
IFS="/"
A=($OUTPUTDIR)
IFS=$SAVEIFS

# do we need universal way or hard-coded tmp is enough?
tmpdir=$(dirname $(mktemp -u))

if [[ $OUTPUTDIR == $tmpdir/* ]]; then
    OMITDIR="$tmpdir/${A[2]}"
    echo "Outputdir = $OUTPUTDIR, tmpdir = $tmpdir, Omitdir = $OMITDIR"
    find "$tmpdir" ! \( -path "$OMITDIR" -prune -o -path "$tmpdir" \) -exec cp -r {} $OUTPUTDIR \;
else
    find "$tmpdir" ! -path "$tmpdir" -exec cp -r {} $OUTPUTDIR \;
fi

Diff tar не использую, в последствии используется mksquashfs. Оно получше будет.

backbone Решил попроще, с массивом

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

Можно еще сделать грязный хак.
Переименовать taskdir в .taskdir, сделать cp -r и переименовать обратно.

Deleted
()
Ответ на: комментарий от UVV

find ... cp -r

Если в $tmpdir будут папки с файлами, то и сами файлы скопируются в $OUTPUTDIR и ещё и папки с этими файлами рекурсивно. Вообще, скрипт больше похож на жёпу, извините. На самом деле нет. Хороший скрипт, просто иногда может работать не так как надо.

anonymous
()
Ответ на: комментарий от anonymous

Если в $tmpdir будут папки с файлами, то и сами файлы скопируютс

т.е. стоит добавить -depth 1? Попробую, спасибо.

UVV ★★★★★
() автор топика

Некропостинг

cp /tmp/!(taskdir) /tmp/taskdir/outputpath
ececbanwew
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.