web-dev-qa-db-ja.com

フォルダー内の4番目ごとのファイルをコピーする方法

00802_Bla_Aquarium_XXXXX.jpgのような名前のフォルダーに多くのファイルがあります。すべての4thファイルをサブフォルダーにコピーして、selected/と言う必要があります。

00802_Bla_Aquarium_00020.jpg <= this one
00802_Bla_Aquarium_00021.jpg
00802_Bla_Aquarium_00022.jpg
00802_Bla_Aquarium_00023.jpg
00802_Bla_Aquarium_00024.jpg <= this one
00802_Bla_Aquarium_00025.jpg
00802_Bla_Aquarium_00026.jpg
00802_Bla_Aquarium_00027.jpg
00802_Bla_Aquarium_00028.jpg <= this one
00802_Bla_Aquarium_00029.jpg

どうすればよいですか?

15
aebersold

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

Bashでは、面白い可能性があり、ここではかなりうまくいきます。

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

これは間違いなく最も短くて最も効率的な答えです。サブシェル、ループ、パイプ、awkward外部プロセスはありません。 cpへの1つのフォーク(とにかく避けられないこと)と1つのbashブレースの展開とグロブ(ファイルの数がわかっているので、完全に取り除くことができます)。

7
gniourf_gniourf

単にbashを使用すると、次のことができます。

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

パターン ./*.jpgは、bash manによって指定されたファイル名のアルファベット順にソートされたリストに置き換えられるため、目的に合うはずです。

5
jfg956

Rubyがインストールされている場合は、次のワンライナーを使用できます。選択したディレクトリが存在することを前提としています。

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

現在のディレクトリにある拡張子.jpgのすべてのファイルのリストを取得し、それを4つの要素のリストにスライスし、最初の要素をそのような各リストから現在のディレクトリで選択されているディレクトリにコピーします。

1
N.N.

GUIファイルマネージャーを使用して、ウィンドウの境界線のサイズを変更し、5つのファイルごとに1つの行を占めたら、マウスを使用して最初の列を選択します...

1
John Chain

ファイル名に改行がないことがわかっている場合は、以下を使用できます。

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
jfg956