Как скопировать каждый 4-й файл в папке

Интересная идея реализовать это базировалась в файловой системе, но ничто как этот не существует к моему знанию. Кроме нескольких дополнений, пытающихся спрятаться достаточно глубоко на верхние слои фс для получения раннего, держатся данные (Обновление: Все попадает в саму эту категорию), я боюсь, что Вы ограничены менее удовлетворяющими процессами регулярной индексации.

То, что могло бы прибыть самое близкое к тому, что Вы ищете, могло бы быть libferris виртуальной файловой системой.

В мире индексации Вы могли бы хотеть смотреть на проблеск, который, по крайней мере, может обновить и добавить его индекс.

Обновление: Я просто считал материал обо "Всем", и это, кажется, не свойственно к FS также, таким образом, libferris не то, что далеко, плюс он также позволяет индексировать содержание, не просто имена файлов. Это действительно удовлетворяет Вашу потребность того, чтобы быть актуальным в любом случае.

15
21.12.2012, 12:17
8 ответов

С zsh Вы могли сделать:

n=0; cp 00802_Bla_Aquarium_?????.jpg(^e:'((n++%4))':) /some/place

POSIXly, та же идея, просто более подробная:

# put the file list in the positional parameters ($1, $2...).
# the files are sorted in alphanumeric order by the shell globbing
set -- 00802_Bla_Aquarium_?????.jpg

n=0
# loop through the files, increasing a counter at each iteration.
for i do
  # every 4th iteration, append the current file to the end of the list
  [ "$(($n % 4))" -eq 0 ] && set -- "$@" "$i"

  # and pop the current file from the head of the list
  shift
  n=$(($n + 1))
done

# now "$@" contains the files that have been appended.
cp -- "$@" /some/place

Так как те имена файлов не содержат символов пробела или подстановочных символов, Вы могли также сделать:

cp $(printf '%s\n' 00802_Bla_Aquarium_?????.jpg | awk 'NR%4 == 1') /some/place
12
27.01.2020, 19:49
  • 1
    Можете Вы помещать комментарий также в код posix –  Rahul Patil 21.12.2012, 12:47
  • 2
    @ChrisDown, for i do является стандартным и на самом деле более портативным, чем for i; do и канонический способ циклично выполниться по позиционным параметрам. –  Stéphane Chazelas 21.12.2012, 19:34

В ударе, забавной возможности, которая будет работать скорее хорошо здесь:

cp 00802_Bla_Aquarium_*{00..99..4}.jpg selected

Это - определенно самый короткий и самый эффективный ответ: никакая подоболочка, никакой цикл, никакой канал, нет awkопека внешний процесс; всего одно ветвление к cp (что Вы не можете избежать так или иначе), и одно расширение фигурной скобки удара и шарик (что можно избавиться от в целом, так как Вы знаете, сколько файлов Вы имеете).

7
27.01.2020, 19:49
  • 1
    … и 2 предположения: файлы нумеруются непрерывно, и первый является делимым с 4. –  manatwork 21.12.2012, 19:23
  • 2
    @manatwork без проблем, если сначала каждый не является делимым 4: например, cp 00802_Bla_Aquarium_*{03..99..4}.jpg selected если Вы хотите 3 mod 4. (Я использую замечательное то, которое 100 является делимым 4). Теперь, о непрерывно пронумерованных файлах, все другие ответы принимают то же. –  gniourf_gniourf 21.12.2012, 19:26
  • 3
    Который другие ответы принимают непрерывную нумерацию? Я нашел только комментарий Ulrich Schwarz и никакой такой ответ. –  manatwork 21.12.2012, 19:38

Просто с ударом, можно сделать:

n=0
for file in ./*.jpg; do
   test $n -eq 0 && cp "$file" selected/
   n=$((n+1))
   n=$((n%4))
done

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

5
27.01.2020, 19:49
  • 1
    В ударе, Ваших трех строках в for цикл может быть заменен просто этой строкой: (((++n)%4)) || cp "$file" selected/. ;-). Проблема, хотя то, что Вы разветвляетесь на a cp для каждого файла, который не действительно эффективен. –  gniourf_gniourf 21.12.2012, 19:33

Если Вы имеете ruby установленный можно использовать следующую остроту. Обратите внимание, что это предполагает, что выбранный каталог существует.

ruby -rfileutils -e 'files = Dir.glob("*.jpg").each_slice(4) { |file| FileUtils.cp(file.first, "selected/" + file.first) }'

Это берет список всех файлов с расширением .jpg в текущем каталоге и нарезает его в списки четырех элементов и копирует первый элемент от каждого такого списка до каталога, выбранного в текущем каталоге.

1
27.01.2020, 19:49

Если Вы знаете, что у Вас не будет новых строк в Ваших именах файлов, Вы могли бы использовать:

find . -maxdepth 1 -name "*.jpg" | sort | while IFS= read -r file; do
  cp "$file" selected/
  IFS= read -r; IFS= read -r; IFS= read -r
done
1
27.01.2020, 19:49
  • 1
    @Gilles: спасибо за редактирование. Я удалил файловую переменную в этом чтении 3, хотя, поскольку я хочу указать, что они не нужны. –  jfg956 22.12.2012, 13:11

Рассмотрение stackoverflow.com/q/4553751/789593, который предлагает решение скопировать каждое второе как @N.N. упомянутый, очень простое решение было бы:

  • Удалите первый файл из стартовой папки
  • Скопируйте каждый второй от стартовой папки до промежуточной папки
  • Скопируйте каждый второй с промежуточной папки в заключительную папку
  • Добавьте первый файл вручную

Это не может быть очень эффективно, поскольку это требует дополнительного бита шага копии, который должно быть очень легко сделать.

-1
27.01.2020, 19:49

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

1
27.01.2020, 19:49

Это решение основано на текстовых утилитах, но должно работать и в менее продвинутых оболочках:

cp `ls * | awk 'NR % 4 == 0'` selected

Обратите внимание, что это может привести к поломке, если количество файлов слишком велико. В этом случае я бы пошел с более медленным способом xargs:

ls * | awk 'NR % 4 == 0' | xargs -i cp {} selected
0
13.04.2021, 17:57

Теги

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