我有一个python脚本,可以根据特定的通配符模式和特征打印出文件名。然后,我将一些命令传送到此打印输出列表,并用xargs rm
删除列出的文件。该脚本在UNIX服务器上运行,通常,我将按以下方式运行脚本:
python deletefiles.py <directory> <wildcard1> | tee deletedfiles.txt | xargs rm
这一切正常运行,但是我试图找到一种方法,使tee
和xargs rm
命令已经在脚本中,以便用户不必将其键入到脚本中。命令。
我已经看过网上了,人们对import subprocess
说,但是我不了解如何结合我的脚本使用它的完整语法。
截至目前,在unix系统上运行的代码很简单
if len(sys.argv) == 3:
try:
input_directory = sys.argv[1]
input_delete = sys.argv[2].split(',') \\patterns to delete
except ValueError:
"Please enter a valid input"
我想做的是实现对另一个参数的检查,分析/删除,其中analyze
仅允许脚本执行打印文件名的工作,并且如果参数为delete
,脚本将xargs rm
和tee
这些文件。
我不确定如何解决这个问题,因为使用python脚本打印文件的主要目的是使xargs rm
和tee deletedfiles.txt
在删除时有一些不足之处/保存到文本文件。我想知道是否有办法在python脚本中有条件地做到这一点
如果我需要提供有关脚本的更多信息,我很乐意
答案 0 :(得分:0)
您可以将它们作为子进程运行。不过,还有更好的选择。见下文。
假设files
包含您的文件名,
from subprocess import Popen, PIPE
p = subprocess.Popen("tee '{0}' | xargs rm".format(teefile),
shell=True, stdin=PIPE)
p.communicate('\n'.join(files))
但是,这两种操作在Python本机中都是微不足道的。
with open(teefile, "w") as tee:
for file in files:
tee.write(file + '\n')
os.unlink(file)
我想您会同意后者更简单,更优雅(尽管在Python 3中,subprocess
也可以变得更简单;您确实想准备尽快转换为Python 3。)>
答案 1 :(得分:-1)
本来我只是想发表评论,但我认为这更容易理解。
Python有一个名为argparse的模块来处理命令行参数。这些示例有些混乱,因此建议您凝视下面的get_args
,直到有意义为止。
您可以尝试在python脚本本身中完成所有这些操作,而不必尝试将其通过管道传递到tee
和xargs rm
。
这里有一个您可以借鉴的示例:
#!/usr/bin/env python2
# allows us to use python3 print function
from __future__ import print_function
import os
import fnmatch
import sys
import argparse
def get_args():
parser = argparse.ArgumentParser()
# note directory has `required=True`, that means the user must provide it
parser.add_argument("--directory", help="Directory to analyze", required=True)
# store_true stores a boolean depending on whether or not the flag was present
parser.add_argument("--delete", help="Delete the files which should be removed", action="store_true", default=False)
args = parser.parse_args() # parses, makes sure all conditions are met, exits if user didn't provide a filename
return args
def analyze(directory):
# do whatever wildcarding here to return a list of files
# heres just an example, remove all *.txt files recursively
files_to_delete = []
for root, dirnames, filenames in os.walk(directory):
# fnmatch is unix-like filename matching
for filename in fnmatch.filter(filenames, "*.txt"):
# abspath gives us the full path, root is the original directory
files_to_delete.append(os.path.abspath(os.path.join(root, filename)))
return files_to_delete
def delete(files):
# write to deleted_files.txt in this function
deleted_file = open("deleted_files.txt", 'w')
for f in files:
if os.path.exists(f): # filepath exists
if os.path.isfile(f): # is a file (not a directory)
os.remove(f) # remove it
deleted_file.write("{}\n".format(f)) # write to the file
else:
print("Could not remove {}, is not a file".format(f), file=sys.stderr)
else:
print("Could not remove {}, does not exist".format(f), file=sys.stderr)
deleted_file.close()
def main():
args = get_args()
files = analyze(args.directory)
# if the user gave us the --delete flag
if args.delete:
delete(files)
else:
# just print it out to the user
for f in files:
print(f)
if __name__ == "__main__":
main()
如果您只想保存应删除的文件,请将输出重定向到文件
python2.7 deletefiles.py --directory test_dir > files_to_delete.txt
如果要删除它们:
python2.7 deletefiles.py --directory test_dir --delete
然后您可以cat deleted_files.txt
来获取已删除的文件。
这里有一些我使用的功能的文档:
fnmatch.filter
,sys.stderr
,os.path.join
,os.path.abspath
,os.path.isfile
,os.walk
,os.remove
如果要删除目录,请查看os.removedirs