Python 批量删除两个文件中较小的一个

Python 批量删除两个文件中较小的一个,python,perl,Python,Perl,我正在寻找一种方法,根据下面提到的标准对一堆文件进行批量重命名: 文件列表与此类似,应为字母数字: A20102-1.loc.txt A20100102.loc.txt A20100103-1.loc.txt A20100103.loc.txt ……等等 下面的伪代码与我希望它的行为方式非常接近,但我试图弄清楚sed、awk、python、perl还是bash脚本是正确的选择(我正在检查这些选项,以便弄清楚我可能需要深入研究哪种实现): 谢谢你的建议

我正在寻找一种方法,根据下面提到的标准对一堆文件进行批量重命名:

文件列表与此类似,应为字母数字:

  • A20102-1.loc.txt
  • A20100102.loc.txt
  • A20100103-1.loc.txt
  • A20100103.loc.txt ……等等
下面的伪代码与我希望它的行为方式非常接近,但我试图弄清楚sed、awk、python、perl还是bash脚本是正确的选择(我正在检查这些选项,以便弄清楚我可能需要深入研究哪种实现):


谢谢你的建议$currentPrefix=”“; $previousFile=“”; 而(){ /([A-Z]+[0-9]+)-?[0-9]*.loc.txt/; 如果($1相等$currentPrefix){ 如果(-s$\u<-s$previousFile){ 取消链接(美元); }否则{ 取消链接($previousFile); $previousFile=$\uU4; } }否则{ $currentPrefix=$1; $previousFile=$\uU4; } } 还有另一个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
导入全局
导入操作系统
进口稀土
currentPrefix=“”
previousFile=“”
对于排序后的文件名(glob.glob('*.txt')):
match=re.match(r'([A-Z]+[0-9]+)-?[0-9]*.loc.txt',文件名)
如果match和match.group(1)=currentPrefix:
如果os.stat(文件名).st_size

注意,您需要对文件进行排序,因为GOLB不按字典顺序返回它们…

< P>我将在Perl发布一个解决方案,仅仅因为您不认为它是可能的:
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])
$currentPrefix=”“;
$previousFile=“”;
而(){
/([A-Z]+[0-9]+)-?[0-9]*.loc.txt/;
如果($1相等$currentPrefix){
如果(-s$\u<-s$previousFile){
取消链接(美元);
}否则{
取消链接($previousFile);
$previousFile=$\uU4;
}
}否则{
$currentPrefix=$1;
$previousFile=$\uU4;
}
}
还有另一个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
导入全局
导入操作系统
进口稀土
currentPrefix=“”
previousFile=“”
对于排序后的文件名(glob.glob('*.txt')):
match=re.match(r'([A-Z]+[0-9]+)-?[0-9]*.loc.txt',文件名)
如果match和match.group(1)=currentPrefix:
如果os.stat(文件名).st_size
请注意,您需要对文件进行排序,因为glob不会按字典顺序返回它们

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')
我认为这应该行得通

>>> rm_smaller_of('[A-Z]\d{8}$', '/home/you/list')

我的条目:不是很简洁,但希望可读

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)

我的条目:不是很简洁,但希望可读

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)

为什么不先决定要用什么编写解决方案呢?好的,python可能对我来说是最好的。你说的“小”或“大”文件是什么意思?你在看文件大小吗?哪个文件名按字母顺序排在第一位?还有别的吗?@AdamRosenfield是的;按字母顺序较小/较大:文件大小。谢谢你clarifying@jml然后编辑你的帖子。并重新标记它!!为什么不先决定要用什么编写解决方案呢?好的,python可能对我来说是最好的。你说的“小”或“大”文件是什么意思?你在看文件大小吗?哪个文件名按字母顺序排在第一位?还有别的吗?@AdamRosenfield是的;按字母顺序较小/较大:文件大小。谢谢你clarifying@jml然后编辑你的帖子。并重新标记它!!太好了,@Drogans!谢谢我也会尝试一下。我在“for entry in files:”上遇到一个错误,因为没有定义“files”。我遗漏了什么?起初我打算将
os.listdir(dir)
分配给
文件
,但我认为,随着文件被删除,它可能会变得丑陋。我改了。太好了,Drogans!谢谢我也会尝试一下。我在“for entry in files:”上遇到一个错误,因为没有定义“files”。我遗漏了什么?起初我打算将
os.listdir(dir)
分配给
文件
,但我认为,随着文件被删除,它可能会变得丑陋。我改变了它。我发现你的代码非常可读;非常感谢。我还没有试过,但我想问一下,如果文件中有操作系统根据副本添加的“错误”字符,是否可以适当地重命名文件-例如,如果“A20100102-1.loc.txt”是较大的文件,它看起来可以将其重命名为“A20100102.loc.txt”,对吗?我发现您的代码非常可读;非常感谢。我还没有试过,但我想问一下,如果操作系统在重复字符的基础上添加了“错误”字符,这是否会适当地重命名文件-例如,如果“A20100102-1.loc.txt”是较大的文件,它看起来可以将其重命名为“A20100102.loc.txt”,对吗?这对我很有效;我稍微修改了它,以便在必要时处理文件重命名;我稍微修改了它,以便在必要时处理文件重命名。