2013-04-15 60 views
1

我想將這行包含在python腳本中。os.system抱怨大括號

!#/bin/bash/env python 

import os 

os.system("paste <(awk '!/^($|[:space:]*#)/{print $0}' file1) <(awk '!/^($|[:space:]*#)/{print $0} file2) > out_file") 

當從bash直接運行時,該命令是完全正確的。然而,在腳本中,我得到:

sh: -c: line0: syntax error near unexpected token `(' 

的問題仍然存在,使用時簡單:

os.system("paste <(cat file1) > output_file") 

任何想法?

+5

它看起來像你的默認shell是'sh',而不是'bash'。而且'sh'命令行都是無效的。 – abarnert

+0

@MartijnPieters:他沒有使用'subprocess',他使用'os.system'。在Unix系統中,它只是調用libc函數'system',它使用...好,這取決於您的操作系統,我們不知道OP使用的操作系統。 – abarnert

+0

@abarnert:對,確實;我的錯。我將指向['man system'](http://linux.die.net/man/3/system),然後指出它使用'/ bin/sh -c'。 –

回答

1

一箭雙鵰一個awk腳本:

awk -v DELIM=' ' '!/^($|[[:space:]]*#)/{a[FNR]=a[FNR]DELIM$0}END{for(i=1;i<=FNR;i++)print substr(a[i],2)}' file1 file2 

這消除了進程替換的需要,是爲此sh標準。

+0

感謝您的建議,但情況稍微複雜一點:我沒有直接指定文件的數量,而是它們是腳本的參數,例如, script.py file1 file2 file3 ...換句話說:我不知道如何將您的示例擴展到N個文件。我一次只能做幾次嗎? file1 + file2 = part1 part1 + file3 = part2 partN-1 + fileN = final? – astabada

+0

@astabada您只需在腳本'file1 file2 ... fileN'之後解析文件列表即可。當單個腳本可以處理它時,多次調用(awk)(每個文件一次)是錯誤的方法。隨後,這消除了你原來的問題。 –

+0

好吧,它的工作原理...進一步(和最後,希望)的問題。你知道任何綜合性的地方去了解命令嗎?人awk似乎不夠。 – astabada

4

當直接從bash運行時,該命令非常好。然而,在腳本中,我得到:

sh: -c: line0: syntax error near unexpected token `(' 

這是因爲裏面的腳本,您正在運行的sh而非bash命令。該命令和簡​​單的命令都使用bash特定的功能。嘗試運行一個sh外殼並輸入相同的行,你會得到相同的錯誤。

os.system呼叫沒有記錄什麼殼,它使用,因爲它是:

通過調用標準C函數system()

在大多數Unix類系統實現的,這叫sh。你可能不應該依賴那個......但你絕對是不應該依靠它調用bash

如果你想運行bash命令,使用subprocess模塊,並運行bash明確:

subprocess.call(['bash', '-c', 'paste <(cat file1) > output_file']) 

你可以,我想,試圖讓引用正確運行bash的外殼內的子shell system使用...但爲什麼打擾?

這是文檔反覆告訴你應該考慮使用subprocess而不是os.system的許多原因之一。

+0

並且你應該添加,爲了在'bash'中運行命令,你可以使用子進程,如[此答案](http://stackoverflow.com/a/4256153/418609)。 – adrianp

+0

@adrianp:那個答案沒有顯示如何明確地使用'bash';它顯示瞭如何在不使用shell的情況下運行'cwm'命令,這不是OP想要的。 – abarnert