我如何在脚本中使用getopts,该脚本将来自单独目录中文件的行附加到新文件?

问题描述 投票:0回答:1

我正在尝试编写一个bash脚本,该脚本包含一个目录,读取目录中的每个文件,然后将该目录中每个文件的第一行追加到一个新文件中。当我在脚本中对变量进行硬编码时,它可以正常工作。

此作品:

#!/bin/bash

rm /local/SomePath/multigene.firstline.btab
touch /local/SomePath/multigene.firstline.btab

btabdir=/local/SomePath/test/*
outfile=/local/SomePath/multigene.firstline.btab

for f in $btabdir
do
    head -1 $f >> $outfile
done

这不起作用:

#!/bin/bash

while getopts ":d:o:" opt; do
  case ${opt} in
    d) btabdir=$OPTARG;;
    o) outfile=$OPTARG;;
  esac
done

rm $outfile
touch $outfile

for f in $btabdir
do
    head -1 $f >> $outfile
done

这是我叫脚本的方式:

bash /local/SomePath/Scripts/btab.besthits.wBp-q_wBm-r.sh -d /local/SomePath/test/* -o /local/SomePath/out.test/multigene.firstline.btab

这是我运行它时得到的:

rm: missing operand
Try 'rm --help' for more information.
touch: missing file operand
Try 'touch --help' for more information.
/local/SomePath/Scripts/btab.besthits.wBp-q_wBm-r.sh: line 23: $outfile: ambiguous redirect

有什么建议吗?我希望能够使用getopts,以便使脚本更通用。谢谢!

bash getopts
1个回答
0
投票

编写bash脚本时,您必须格外注意quotingglobbing

当您使用全域调用脚本(此处为*)时,它会被shell扩展并分解为单词。这是在脚本执行之前发生的。

[例如,如果您执行cat *.txt cat将获取目录中的所有.txt文件作为其参数。它将与调用cat afile.txt nextfile.txt(依此类推)相同。猫将永远不会看到星号。

在您的脚本中,这意味着输入-d /local/SomePath/test/*被展开,例如/local/SomePath/test/someFile /local/SomePath/test/someOtherFile /test/someThirdFile。随后,getopts仅取-d之后的第一个文件作为$btabdir,并且在大小写切换中不处理-o

我建议您首先引用每个变量,最好使用"${name}"样式,并且仅使用带引号的输入来调用脚本。也可以在目录路径中发送它,测试它是否是目录(test -d),然后将for循环更改为for f in "${btabdir}"/*

© www.soinside.com 2019 - 2024. All rights reserved.