скопируйте n количество файлов от одной папки до другой папки

У меня есть папка n количества файлов. Я должен переместить n/2 (или) n/3 файлы от той папки до любой другой папки. Как установить значение n так, чтобы это переместилось точный, они нумеруют файлов?

1
задан 19 November 2014 в 20:35

3 ответа

Вы могли сделать что-то как

k=1; find source/ -type f | while read file; do
     [[ k++ -le 20 ]] && cp "$file" target/ 
done

, Который найдет все файлы в текущем каталоге и скопирует первые 20, которые он находит к target/. Прием $k переменная, которая инициализируется к 1. Затем эти [[ k++ -le 20 ]] && cp означает, "Если $k плюс каждый меньше чем или равен 20, выполните команду CP".

Вышеупомянутое повредится, если Ваши имена файлов будут содержать пробелы или новые строки или другую странность. Если это может быть проблемой, используйте эту более безопасную версию вместо этого:

k=1; find source/ -type f -print0 | 
    while IFS= read -d '' -r file; do 
        [[ k++ -le 20 ]] && cp "$file" target/ 
    done

, Если Вы не должны убывать в подкаталоги, просто сделайте

k=1; for file in *; do [[ k++ -le 20 ]] && cp "$file" target/ ; done

Наконец, для вычисления n на лету, можно сделать (обратите внимание, что это будет также считать подкаталоги)

files=( * ); ## save all files in the current directory in an array
n=$(echo "${#files[@]} / 3 " | bc) ## get the value of n/3
for file in "${files[@]:1:$n}"; do cp "$file" bar/; done

, решение выше должно работать с произвольными именами файлов, даже те включая новые строки.

3
ответ дан 10 November 2019 в 18:08

Сделать часть (например, ⅓), не зная количества заранее,

k=0; for file in *
do
    if [ $((k++ % 3)) -eq 0 ]
    then
        mv "$file" target/
    fi
done

Это захватит каждый третий файл путем хранения под управлением счетчика (k) и действие на каждый файл, для который k трехзначного порядка. Так как я запустил счетчик в 0, это окружит; например, если у Вас будет десять или одиннадцать файлов (или двенадцать), то это переместит четырех из них. 

Если существуют подкаталоги (или экзотические файлы, как FIFOs) в текущем каталоге, и Вы хотите переместить ⅓ из простых файлов, оставляя другие в покое, изменить вышеупомянутое на

k=0; for file in *
do
    if [ -f "$file" ]  &&  [ $((k++ % 3)) -eq 0 ]
    then
        mv "$file" target/
    fi
done

Если Вы хотите убывать в подкаталоги, сказать

shopt -s globstar

и используйте ** вместо *. Если Вы хотите включать имена, которые начинаются с точки (.), Вы должны также shopt -s dotglob.

Вышеупомянутое решение должно работать с произвольными именами файлов, даже имена файлов включая новые строки.

2
ответ дан 10 November 2019 в 18:08

Используйте комбинацию find, sed и xargs:

find /path/to/dir -print0 | sed -nz '1~2p' | xargs -0 cp --target-dir=/some/dir

sed -n '1~2p' печать каждая альтернативная строка, таким образом уменьшая количество до половины. Для создания его одной третью используйте 1~3p. -print0, -z и -0 опции указывают, что мы используем \0 символ (NULL) для разграничивания вещей.

Ссылки:

2
ответ дан 10 November 2019 в 18:08

Другие вопросы по тегам:

Похожие вопросы: