Python bash globbing子流程
如果我有一个目录,我想删除除一个文件以外的所有文件,我可以在bash中执行此操作:Python bash globbing子流程,python,bash,Python,Bash,如果我有一个目录,我想删除除一个文件以外的所有文件,我可以在bash中执行此操作: cd /tmp/a rm -rf !(specialfile) cd - 将其转换为最明显的Python代码对我来说是失败的: >>> subprocess.Popen( 'cd /tmp/a; rm -rf !(specialfile); cd -', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicat
cd /tmp/a
rm -rf !(specialfile)
cd -
将其转换为最明显的Python代码对我来说是失败的:
>>> subprocess.Popen( 'cd /tmp/a; rm -rf !(specialfile); cd -', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
谨此致辞:
('', "/bin/sh: -c: line 0: syntax error near unexpected token `('\n/bin/sh: -c: line 0: `cd /tmp/a; rm -rf !(specialfile); cd -'\n")
Python中第二个最好的东西似乎是:
p = '/tmp/a'
for i in os.listdir( p ):
if i != 'specialfile':
os.remove( os.path.join( p, i ) )
当然,这并不能很好地处理文件和子目录。有更好的方法吗?Update:正如@isedev和OP@JohnSchmitt在评论中指出的,
subprocess.Popen
调用sh
,而不是bash
(和sh
可能是也可能不是bash
,取决于平台),但使用扩展模式匹配操作符!(…)
需要(a)bash
(b)启用extglob
选项(背景信息请参见下文)
因此,答案是:
- 使用通过
命令行选项传递的命令字符串显式调用-c
bash
- 通过
命令行选项打开-O
shell选项(如果没有它,globextglob
会触发OP遇到的语法错误)!(specialfile)
subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在rm
命令之前,将shopt-s extglob;
添加到bash命令字符串中。)
背景:
!(specialfile)
是扩展模式匹配操作符的一个实例(请参见man bash
,部分模式匹配
);默认情况下,这些扩展运算符未启用shopt-s extglob
启用它们(shopt-u extglob
禁用它们)。更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,子流程.Popen
调用sh
,而不是bash
(并且sh
可能是也可能不是bash
,取决于平台),但是使用扩展模式匹配操作符!(…)
需要(a)bash
(b)启用extglob
选项(背景信息请参见下文)
因此,答案是:
- 使用通过
命令行选项传递的命令字符串显式调用-c
bash
- 通过
命令行选项打开-O
shell选项(如果没有它,globextglob
会触发OP遇到的语法错误)!(specialfile)
subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在rm
命令之前,将shopt-s extglob;
添加到bash命令字符串中。)
背景:
!(specialfile)
是扩展模式匹配操作符的一个实例(请参见man bash
,部分模式匹配
);默认情况下,这些扩展运算符未启用shopt-s extglob
启用它们(shopt-u extglob
禁用它们)。更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,子流程.Popen
调用sh
,而不是bash
(并且sh
可能是也可能不是bash
,取决于平台),但是使用扩展模式匹配操作符!(…)
需要(a)bash
(b)启用extglob
选项(背景信息请参见下文)
因此,答案是:
- 使用通过
命令行选项传递的命令字符串显式调用-c
bash
- 通过
命令行选项打开-O
shell选项(如果没有它,globextglob
会触发OP遇到的语法错误)!(specialfile)
subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在rm
命令之前,将shopt-s extglob;
添加到bash命令字符串中。)
背景:
!(specialfile)
是扩展模式匹配操作符的一个实例(请参见man bash
,部分模式匹配
);默认情况下,这些扩展运算符未启用shopt-s extglob
启用它们(shopt-u extglob
禁用它们)。更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,子流程.Popen
调用sh
,而不是bash
(并且sh
可能是也可能不是bash
,取决于平台),但是使用扩展模式匹配操作符!(…)
需要(a)bash
(b)启用extglob
选项(背景信息请参见下文)
因此,答案是:
- 使用通过
命令行选项传递的命令字符串显式调用-c
bash
- 通过
命令行选项打开-O
shell选项(如果没有它,globextglob
会触发OP遇到的语法错误)!(specialfile)
subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在rm
命令之前,将shopt-s extglob;
添加到bash命令字符串中。)
背景:
!(specialfile)
是扩展模式匹配操作符的一个实例(请参见man bash
,部分模式匹配
);默认情况下,这些扩展运算符未启用shopt-s extglob
启用它们(shopt-u extglob
禁用它们)。您可以使用@Bakuriu提到的os.walk。非常重要的是从下到上遍历目录树,以便始终有空目录,但包含“specialfile”的目录除外。这就是为什么在os.rmdir
命令中需要try
子句的原因
import os
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
if name != 'specialfile':
os.remove(os.path.join(root, name))
for name in dirs:
try:
os.rmdir(os.path.join(root, name))
except:
pass
你可以