"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호출 스크립트를 사용할 때 두 개의 인수가 아닌 하나 -o2의 인수) 로 확장됩니다 .-a 2-a2

옵션이 아닌 인수 다음에 옵션을 허용하므로 아마도 joinGNU일 것입니다 . join비어 있으면 이는 "$outer"옵션이 아닌 인수이며 그렇게 -시작하지 않기 때문에 파일 이름으로 처리되고 join예상하지 못한 세 번째 파일 이름이 제공되는 것에 대해 불평합니다.

가변 개수의 인수를 갖는 변수를 원하면 배열을 사용하십시오.

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

관련 정보