0

下記の基準に基づいて、一連のファイルの一括名前変更を行う方法を探しています。

ファイルリストは次のようになり、英数字である必要があります。

  • A20100102-1.loc.txt
  • A20100102.loc.txt
  • A20100103-1.loc.txt
  • A20100103.loc.txt...など。

次の擬似コードは、私が望む動作にかなり近いですが、sed、awk、python、perl、またはbashスクリプトが進むべき道であるかどうかを理解しようとしています(オプションを調べていますどの実装をより深く掘り下げたいかを理解するために):

for all_files_in_dir:{
  if(currentfile.name is_close_to previousfile.name){  //maybe regex here
    var small_file = find_smaller_file_filename(currentfile.filesize, previousfile.filesize);
    sys.remove(small_file);
  }
}

提案をありがとう!

4

3 に答える 3

2
import os
import re

def rm_smaller_of(regex, dir):
    for entry in os.listdir(dir):
        if re.match(regex, entry[:9]):
            matches = [(os.stat(f).st_size, f) for f in os.listdir(dir) 
                        if f[:9] == entry[:9]]
            matches.sort(reverse=True)
            for d in matches[1:]:
                os.remove(d[1])

これでうまくいくと思います。

>>> rm_smaller_of('[A-Z]\d{8}$', '/home/you/list')
于 2012-11-05T19:26:00.053 に答える
1

私のエントリ:それほど簡潔ではありませんが、うまくいけば読みやすくなります。

import sys, os
from collections import defaultdict

filenames = sys.argv[1:]

# collect like-named files
groups = defaultdict(set)
for filename in filenames:
    key = filename.split('.')[0].split("-")[0]
    groups[key].add(filename)

# work on each group
for names in groups.values():
    target_name = sorted(names)[0] # or min(names, key=len), or whatever
    largest_file = max(names, key=os.path.getsize)

    os.rename(largest_file, target_name)

    to_remove = names.difference((largest_file, target_name))
    for name in to_remove:
        os.remove(name)
于 2012-11-05T19:52:23.563 に答える
1

あなたがそれを可能性として考えなかったという理由だけで、私はPerlで解決策を投稿します:)

$currentPrefix = "";
$previousFile = "";
while (<*.txt>) {
  /([A-Z]+[0-9]+)-?[0-9]*.loc.txt/;
  if ($1 eq $currentPrefix) {
    if (-s $_ < -s $previousFile) {
      unlink($_);
    } else {
      unlink($previousFile);
      $previousFile = $_;
    }
  } else {
    $currentPrefix = $1;
    $previousFile = $_;
  }
}

そしてPythonの別の解決策:

import glob
import os
import re

currentPrefix = ""
previousFile = ""
for filename in sorted(glob.glob('*.txt')):
  match = re.match(r'([A-Z]+[0-9]+)-?[0-9]*.loc.txt', filename)
  if match and match.group(1) == currentPrefix:
    if os.stat(filename).st_size < os.stat(previousFile).st_size:
      os.remove(filename)
    else:
      os.remove(previousFile)
      previousFile = filename
  else:
    currentPrefix = match.group(1)
    previousFile = filename

globは辞書式順序でファイルを返さないため、ファイルを並べ替える必要があることに注意してください…</ p>

于 2012-11-05T19:07:39.523 に答える