在 python 代码中插入 bash 脚本



我正在尝试从python代码执行bash脚本。bash 脚本在 for 循环内的管道中有一些 grep 命令。当我运行bash脚本本身时,它没有给出任何错误,但是当我在python代码中使用它时,它说:grep:write error。

我在python中调用的命令是:

subprocess.call("./change_names.sh",shell=True)

bash 脚本是:

#!/usr/bin/env bash
for file in *.bam;do new_file=`samtools view -h $file | grep -P 'tSM:' | head -n 1 | sed 's/.+SM:(.+)/1/' | sed 's/t.+//'`;rename s/$file/$new_file.bam/ $file;done

我错过了什么?

当您运行不需要命令行中任何内容的简单命令时,不应使用shell=True

subprocess_call(["./change_names.sh"])

外壳脚本中存在多个问题。 这是一个注释重构。

#!/usr/bin/env bash
for file in *.bam; do
# Use modern command substitution syntax; fix quoting
new_file=$(samtools view -h "$file" |
grep -P 'tSM:' |
# refactor to a single sed script
sed -n 's/.+SM:([^t]+).*/1/p;q')
# Fix quoting some more; don't use rename
mv "$file" "$new_file.bam"
done

grep -P在这里似乎没有必要或有用,但是如果没有输入的示例,我也不愿意将其重构到sed脚本中。 我希望我猜对了您的sed版本如何处理+t转义,这些转义并非完全可移植。

这仍会产生一条警告,指出在某些情况下,您不会读取grep的所有输出。更好的解决方案可能是将更多内容重构到您的 Python 脚本中。

import glob
for file in glob.glob('*.bam'):
new_name = subprocess.check_output(['samtools', 'view', '-h', file])
for line in new_name.split('n'):
if 'tSM:' in line:
dest = line.split('t')[0].split('SM:')[-1] + '.bam'
os.rename(file, dest)
break

嗨,请尝试以下修改,这将解决您的问题。

for file in *.bam;do new_file=`unbuffer samtools view -h $file | grep -P 'tSM:' | head -n 1 | sed 's/.+SM:(.+)/1/' | sed 's/t.+//'`;rename s/$file/$new_file.bam/ $file;done

或者尝试将您的标准错误重定向到 dev/null,如下所示

for file in *.bam;do new_file=`samtools view -h $file >2>/dev/null | grep -P 'tSM:' | head -n 1 | sed 's/.+SM:(.+)/1/' | sed 's/t.+//'`;rename s/$file/$new_file.bam/ $file;done

您的实际问题是此命令samtools view -h $file当您从python运行脚本时,您应该提供如下所示的完整路径:-

/fullpath/samtools view -h $file 

最新更新