「join:追加オペランド '/dev/fd/62'」エラーが表示されるのはなぜですか?

「join:追加オペランド '/dev/fd/62'」エラーが表示されるのはなぜですか?

スクリプトがありますequijoin2

#! /bin/bash

# default args                                                                                                                                                                    
delim="," # CSV by default                                                                                                                                                        
outer=""
outerfile=""
# Parse flagged arguments:                                                                                                                                                        
while getopts "o:td:" flag
do
  case $flag in
    d) delim=$OPTARG;;
    t) delim="\t";;
    o) outer="-a $OPTARG";;
    ?) exit;;
  esac
done
# Delete the flagged arguments:                                                                                                                                                   
shift $(($OPTIND -1))
# two input files                                                                                                                                                                 
f1="$1"
f2="$2"
# cols from the input files                                                                                                                                                       
col1="$3"
col2="$4"


join "$outer" -t "$delim" -1 "$col1" -2 "$col2" <(sort "$f1") <(sort "$f2")

そして2つのファイル

$ cat file1
c c1
b b1
$ cat file2
a a2
c c2
b b2

最後のコマンドが失敗するのはなぜですか?ありがとうございます。

$ equijoin2 -o 2  -d " " file1 file2 1 1
a a2
b b1 b2
c c1 c2
$ equijoin2 -o 1  -d " " file1 file2 1 1
b b1 b2
c c1 c2
$ equijoin2   -d " " file1 file2 1 1
join: extra operand '/dev/fd/62'

ベストアンサー1

"$outer"引用符で囲まれたスカラー変数なので、常に引数に展開されます。空でも設定されていなくても、空の引数(join呼び出しスクリプトを使用するときは2つの引数ではなく1つ-o2の引数)に展開されます。-a 2-a2

オプションではなく引数の後にオプションを受け入れるので、おそらくjoinGNUです。join空の場合、これは"$outer"オプションではなく引数であり、それを起動しない-ため、ファイル名として扱われ、join予期しない3番目のファイル名が提供されたことについて文句を言います。

可変数の引数を持つ変数が必要な場合は、配列を使用してください。

outer=()
...
(o)
   outer=(-a "$OPTARG");;

...
join "${outer[@]}"

ここでも次のことができます。

outer=
...
(o)
   outer="-a$OPTARG";;
...
join ${outer:+"$outer"} ... <(sort < "$f1") <(sort < "$f2")

または:

unset -v outer
...
(o)
   outer="$OPTARG";;
...
join ${outer+-a "$outer"} ...

zsh(この機能はsh / kshエミュレーションを除いては機能しません。)

その他の注意事項:

  • join -t '\t'動作しません。delim=$'\t'TABテキストを次の場所に保存する必要があります。$delim
  • --コマンドに任意の引数を渡すときに使用する(または可能であればリダイレクトを使用する)ことを忘れないでください。だからsort -- "$f1"またはそのsort < "$f1"代わりに良いですsort "$f1"
  • 算術拡張も分割+globの影響を受けるため、引用符()で囲む必要があります(環境から継承されていない拡張を使用してスクリプトの前半で変更しないshift "$((OPTIND - 1))"ため、ここでは問題ではありませんが、まだ良い習慣です)。 )。bash$IFSIFS

おすすめ記事