![ループ内のベース名に関する問題](https://rvso.com/image/38675/%E3%83%AB%E3%83%BC%E3%83%97%E5%86%85%E3%81%AE%E3%83%99%E3%83%BC%E3%82%B9%E5%90%8D%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E5%95%8F%E9%A1%8C.png)
私はシェル スクリプト プログラミングの初心者で、テキストを読み取って POS タグ付けを実行するソフトウェアを実行しようとしています。実行例に示すように、入力と出力が必要です。
$ cat input.txt | /path/to/tagger/run-Tagger.sh > output.txt
私がやろうとしているのは、この行をテキストだけでなく、特定のフォルダー内のテキスト セットに対して実行し、入力ファイルと同じ名前の出力ファイルを返すことです。そこで、次のスクリプトを実行してみました。
#!/bin/bash
path="/home/rafaeldaddio/Documents/"
program="/home/rafaeldaddio/Documents/LX-Tagger/POSTagger/Tagger/run-Tagger.sh"
for arqin in '/home/rafaeldaddio/Documents/teste/*'
do
out=$(basename $arqin)
output=$path$out
cat $arqin | $program > $output
done
1 つのファイルだけで試したところ、うまくいきましたが、複数のファイルで試すと、次のエラーが発生します。
basename: extra operand ‘/home/rafaeldaddio/Documents/teste/3’
Try 'basename --help' for more information.
./scriptLXTagger.sh: 12: ./scriptLXTagger.sh: cannot create /home/rafaeldaddio/Documents/: Is a directory
私が何を間違っているのか、何か情報はありますか? ありがとうございます。
答え1
を一重引用符で囲んでいます。これは、内部で'/home/rafaeldaddio/Documents/teste/*'
と呼ばれる単一のファイルを探していることを意味します。(そのようなファイルが存在するか、それが意図されたことではないと思われます)。*
teste
これは、for
ループが単一のエントリで実行され、そのファイルが*
basename に渡されることを意味します。
次に、当然ながら basename の引数が多すぎるため、out=$(basename $arqin)
に拡張されます。out=$(basename file1 file2 file3 ... fileN)
簡単な解決策: の周りの引用符を削除します/home/rafaeldaddio/Documents/teste/*
。
答え2
@BenXO はすでに失敗した理由を説明していますが、これほど単純なことにスクリプトは実際には必要ではありません。これをコマンド ラインに直接貼り付けるだけで済みます。
for arqin in /home/rafaeldaddio/Documents/teste/*; do
cat "$arqin" |
/home/rafaeldaddio/Documents/LX-Tagger/POSTagger/Tagger/run-Tagger.sh > \
/home/rafaeldaddio/Documents/$(basename "$arqin");
done
または、cat foo | program
が機能する場合はprogram foo
ほぼ確実に機能し、それが/home/rafaeldaddio/
ホーム ディレクトリであると仮定すると、次のように簡略化できます。
for arqin in ~/Documents/teste/*; do
~/Documents/LX-Tagger/POSTagger/Tagger/run-Tagger.sh "$arqin" > \
~/Documents/$(basename "$arqin");
done