У меня есть папка n количества файлов. Я должен переместить n/2 (или) n/3 файлы от той папки до любой другой папки. Как установить значение n так, чтобы это переместилось точный, они нумеруют файлов?
Вы могли сделать что-то как
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
, решение выше должно работать с произвольными именами файлов, даже те включая новые строки.
Сделать часть (например, ⅓), не зная количества заранее,
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
.
Вышеупомянутое решение должно работать с произвольными именами файлов, даже имена файлов включая новые строки.
Используйте комбинацию 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) для разграничивания вещей.
Ссылки: