bash脚本:循环参数

时间:2013-08-21 21:00:32

标签: shell unix sed

我编写了一个脚本(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 ~

3 个答案:

答案 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标准的shellsed

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.txtfile2.txtfile3.txt,那么"$*"将其作为一件事传递到循环,即{{1} }。当然,这一点并不存在。

file1.txt file2.txt file3.txt扩展为每个参数,一次一个,被视为单个“单词”。这很好,因为它会将前面示例中的"$@"file1.txtfile2.txt正确地视为三项。循环将一次正确接收它们。另外,file3.txt是好的,因为即使你的文件名中有空格,你也会得到正确的行为,因为循环会处理,例如"$@"filename 1filename 2作为三个项目,一个接一个。 (通常情况下,shell将空格视为标记单词的结尾,因此filename 2 and a half看起来像两个项到shell filename 1filename。< / p>

如果未引用1$@,则展开所有位置参数的字词。因此,在这种情况下,它们实际上是相同的(并且这两个都是一个坏主意,因为它们不能保护您免受奇怪命名的文件的侵害)。

这里有所有可能性的可视化:http://wiki.bash-hackers.org/scripting/posparams#mass_usage