我想执行这个make命令首先替换目录中所有csv文件的第一行,然后通过其他行替换逗号的var let = 5;
let x = 3;
x + let -> 8
。
第二个命令工作正常并按预期执行,但第一个命令只替换第一个文件中的行。
有人可以给我一个帮助吗?
@
答案 0 :(得分:3)
第一个sed
命令"失败的原因"是sed
没有重置输入文件之间的行计数器(在您的系统上,在我的Mac OS X机器上都没有,请参阅注释):
$ cat test1
a
b
g
$ cat test2
aa
bb
cc
$ sed -n '=' test1 test2 # the '=' sed command outputs line numbers
1
2
3
4
5
6
这就是为什么第一个sed
命令没有做你想做的事情,它只会影响第一个文件的第一行。
解决方案是遍历文件并为每个文件调用sed
(在Makefile中未经测试):
@for f in $(CURDIR)/foo/npm/*.csv; do \
sed -i '' '1 s/^.*$$/"bar","repository"/g' $f; \
done
使用find
和xargs
也可以,只需确保find
不会在文件夹中向下搜索文件。
编辑:根据对此答案的评论,我建议完全避免在多个文件上使用sed -i
,并将这两个语句转换为for
- 循环(在这种情况下,它们可能会折叠成一个包含两个语句的循环):
@for f in $(CURDIR)/foo/npm/*.csv; do \
sed -i '' '1 s/^.*$$/"bar","repository"/g' $f; \
sed -i '' 's/\(.*\)@/\1","/g' $f; \
done
根据我的经验,与使用for
和find
相比,在Makefile中使用xargs
- 循环似乎更为常见。这可能是由于Unices之间的find
和xargs
版本之间不兼容。如果使用显式循环,它还使Makefile更容易阅读。
答案 1 :(得分:1)
我设法解决:
stmt = "insert into table (col1, col2, col3) values (100, '() string with parantheses ()', 2.3);"
# if it will always be an insert statement, the following will work.
par1 = stmt[stmt.find("(") + 1:stmt.find(") values")]
par2 = stmt[stmt.find("values (") + 8:-2]
par1_list = par1.split(",")
par2_list = par2.split(",")
d = dict(zip(par1_list, par2_list))
print(d) # prints: {' col2': " '() string with parantheses ()'", ' col3': ' 2.3', 'col1': '100'}