我编写了一个脚本(replace.sh),用〜\ n替换〜。我想知道如何用多个参数调用这个脚本。
#!/bin/bash
for i in "$*"
do
sed 's/~/~\n/g' "$i"
done
例如,我想调用./replace.sh text1 text2。它无法读取
text1的内容为:1~1~1。调用脚本后应该是
1 ~
1 ~
1 ~
答案 0 :(得分:4)
在for循环中使用"$@"
:
for i in "$@"
do
sed -i.bak 's/~/~\n/g' "$i"
done
虽然我不确定sed是否按照你在这里描述的那样做。
答案 1 :(得分:2)
这应该足够了:
for i do
sed -i.bak 's/~/~\n/g' "$i"
done
此处便携式变体应适用于任何符合posix标准的shell
和sed
:
for i do
sed 's/~/~\n/g' "$i" > "$i.bak" && cp "$i.bak" "$i"
done
注意:shell in ...
循环的for
部分是可选的。如果不使用,for
默认选择所有参数(即"$@"
),这正是您所期望的。
答案 2 :(得分:1)
其他答案涵盖了您的真实问题。但有一点值得一提的是,当双引号时,$*
和$@
在扩展方面有何不同。 tl; dr 您几乎总是想要"$@"
。
"$*"
扩展为单个字符串,其中包含所有参数,其中第一个字符为IFS
。在实践中,这通常意味着所有参数都是由空格分隔的一个字符串。因此,如果您的参数是file1.txt
,file2.txt
和file3.txt
,那么"$*"
将其作为一件事传递到循环,即{{1} }。当然,这一点并不存在。
file1.txt file2.txt file3.txt
扩展为每个参数,一次一个,被视为单个“单词”。这很好,因为它会将前面示例中的"$@"
,file1.txt
和file2.txt
正确地视为三项。循环将一次正确接收它们。另外,file3.txt
是好的,因为即使你的文件名中有空格,你也会得到正确的行为,因为循环会处理,例如"$@"
,filename 1
,filename 2
作为三个项目,一个接一个。 (通常情况下,shell将空格视为标记单词的结尾,因此filename 2 and a half
看起来像两个项到shell filename 1
和filename
。< / p>
如果未引用1
和$@
,则展开所有位置参数的字词。因此,在这种情况下,它们实际上是相同的(并且这两个都是一个坏主意,因为它们不能保护您免受奇怪命名的文件的侵害)。
这里有所有可能性的可视化:http://wiki.bash-hackers.org/scripting/posparams#mass_usage。