You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

需求:将指定Shell脚本转Python代码或嵌入Python并支持路径变量替换

Converting the Directory Stats Shell Script to Python

Great question! Let's start by recapting what your original shell script does: it outputs a formatted table showing the total size, number of files/subdirectories, and name of each subdirectory in a given path, sorted by the number of files. Below are two approaches to convert this to Python using a variable path (e.g., x = "/usr/bin").

Approach 1: Embed the Shell Script in Python

If you want to reuse your existing shell logic without rewriting everything, you can use Python's subprocess module to run the command dynamically with your path variable. This is ideal if you're comfortable with the original shell behavior and want a quick port.

import subprocess

# Define your target path variable
x = "/usr/bin"

# Calculate the field number for extracting subdirectory names (adjusts for path depth)
path_depth = x.count('/') + 2

# Build the shell command with the dynamic path
shell_cmd = f'''echo -e "Size\tFiles\tDirectory"; paste <(du -sh {x}/*/ | sort -k2 | cut -f1) <(find {x}/*/ | cut -d/ -f{path_depth} | uniq -c | sort -k2 | awk '{{print ($1-1)"\\t"$2}}') | sort -nk2'''

# Run the command and capture output (handle errors gracefully)
try:
    result = subprocess.run(shell_cmd, shell=True, capture_output=True, text=True, check=True)
    print(result.stdout)
except subprocess.CalledProcessError as e:
    print(f"Error running command: {e.stderr}")

Key Notes:

  • The path_depth calculation ensures we correctly extract subdirectory names regardless of how nested your target path is (e.g., /usr/bin vs /home/user/documents).
  • Wrap your path in quotes ("{x}") if it contains spaces or special characters (like * or ?) to avoid shell parsing issues.
  • This relies on Unix-like shell tools (du, find, paste, etc.) being available on your system.

Approach 2: Pure Python Implementation

For cross-platform compatibility and easier long-term modification, rewrite the logic entirely in Python. This eliminates dependencies on external shell tools and gives you more control over edge cases.

import os

def format_size(bytes_size):
    """Convert raw bytes to human-readable format (KB, MB, GB, etc.)"""
    for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
        if bytes_size < 1024:
            return f"{bytes_size:.1f}{unit}"
        bytes_size /= 1024
    return f"{bytes_size:.1f}PB"

def get_directory_stats(dir_path):
    """Calculate total size and number of files/subdirs for a given directory"""
    total_size = 0
    total_entries = 0
    
    try:
        for root, dirs, files in os.walk(dir_path):
            # Add size of all files (skip unreadable files)
            for file in files:
                file_path = os.path.join(root, file)
                try:
                    total_size += os.path.getsize(file_path)
                except OSError:
                    continue
            # Count all directories and files in the current tree level
            total_entries += len(dirs) + len(files)
    except OSError:
        # Skip directories we can't access (e.g., permission denied)
        return None, None
    
    return format_size(total_size), total_entries

# Define your target path variable
x = "/usr/bin"

# Collect stats for all subdirectories
directory_stats = []
for entry in os.scandir(x):
    if entry.is_dir(follow_symlinks=False):
        size, count = get_directory_stats(entry.path)
        if size and count:
            directory_stats.append((count, size, entry.name))

# Sort by number of entries (numerical order)
directory_stats.sort()

# Print formatted table
print(f"{'Size':<8} {'Files':<6} Directory")
for count, size, name in directory_stats:
    print(f"{size:<8} {count:<6} {name}")

Key Notes:

  • The format_size function replicates the human-readable output of du -sh.
  • We handle permission errors by skipping unreadable files/directories, making the script more robust.
  • os.scandir is more efficient than os.listdir for checking directory entries.
  • By default, this doesn't follow symbolic links (matching du's default behavior). To follow symlinks, change follow_symlinks=False to True in entry.is_dir().

内容的提问来源于stack exchange,提问作者robinder singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:07:02