스크립트가 있습니다 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
-a
2
옵션이 아닌 인수 다음에 옵션을 허용하므로 아마도 join
GNU일 것입니다 . 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
$IFS
IFS