将通配符 * 传递给(bash?)脚本

将通配符 * 传递给(bash?)脚本

我想从中等大小的文本文件集合中删除所有看起来像“@n”、“@R”等的颜色代码。

因此,在名为“remove_cc”的文件中,我编写了以下内容:

sed -ie 's/@r//g' $1
sed -ie 's/@g//g' $1
sed -ie 's/@y//g' $1
sed -ie 's/@b//g' $1
sed -ie 's/@m//g' $1
sed -ie 's/@c//g' $1
sed -ie 's/@n//g' $1
sed -ie 's/@R//g' $1
sed -ie 's/@G//g' $1
sed -ie 's/@Y//g' $1
sed -ie 's/@B//g' $1
sed -ie 's/@M//g' $1
sed -ie 's/@C//g' $1
sed -ie 's/@N//g' $1
sed -ie 's/@W//g' $1
sed -ie 's/@K//g' $1

无论如何,如果我像这样使用它,该脚本会非常有效:./remove_cc file.txt

但是,如果我输入./remove_cc *.txt一个包含许多 txt 文件的文件夹,并且我想在其中运行脚本,则它不会执行任何操作。 ./remove_cc *同样无效。

有没有办法解决这个问题,使其有效?

答案1

当您键入 时./remove_cc *,shell 将其更改为./remove_cc file1.txt file2.txt file3.txt etc,并以这种方式运行您的脚本。您的脚本仅查看$1第一个参数(file1.txt)。

最通用的方法是依次循环每个参数。 "$@"展开为所有参数的列表,我们可以使用for它们来循环。

for n in "$@" ; do
    sed -ie 's/@r//g' "$n"
    ...
done

在这种特殊情况下,由于sed将采用多个文件名,因此您可以简化:

sed -ie 's/@r//g' "$@"

请注意,编写 shell 脚本时注意引号很重要。例如,如果没有引号,脚本将无法处理名为My Text File.txt.

答案2

只需使用

 for x in *
 do
     ./remove_cc $x
 done

顺便说一句,您可以将所有 sed 组合在一行中

sed -i \
    -e 's/@r//g' -e 's/@g//g' -e 's/@y//g' -e 's/@b//g' \
    -e 's/@m//g' -e 's/@c//g' -e 's/@n//g' -e 's/@R//g' \
    -e 's/@G//g' -e 's/@Y//g' -e 's/@B//g' -e 's/@M//g' \
    -e 's/@C//g' -e 's/@N//g' -e 's/@W//g' -e 's/@K//g' \
    $1

您还可以使用分号连接 sed 命令:

sed -i -e 's/@r//g;s/@g//g;s/@y//g' $1

或者只使用字符列表

sed -i -e s/@[rgbcmyRGBCMY]//g $1

或者

 sed -i -e s/@[rgbcmyRGBCMY]//g *

(一定要检查我已经把所有的信都放好了)

答案3

使用"$@"而不是$1.或者引用通配符:

$ bash -c 'echo $1' 'some command' '*'
file1 file2
$ bash -c 'echo "$@"' 'some command' *
file1 file2

答案4

如果您不想更改脚本,您也可以通过运行以下命令来使用 xargs(考虑到您拥有它或者它在您的平台上可用):

ls *.txt | xargs -L1 ./remove_cc

xargs 是一个实用程序,它接受 stdin 并将其转换为要运行的命令上的命令参数。它具有 -L 标志,用于限制单次执行中使用的输入行数。

相关内容