조회에 선택적 그룹화 매개변수 목록을 추가하는 방법은 무엇입니까?
예를 들어 기본 매개변수 배열을 사용하여 지정된 다른 변수 조건에 관계없이 항상 검색되는 파일을 정의합니다.
# args to find any files ending _count or _scan
._. fargs=( -type f -name '*_count' -o -name '*_scan' )
._. cd /sys/fs/ext4/sda1
._. find . \( "${fargs[@]}" \) 2> /dev/null
./mb_min_to_scan
./errors_count
./mb_max_to_scan
./msg_count
./warning_count
선택적 추가 매개변수 추가
._. fpterm=warning
._. fpterm2=max
._. fANDargs=( -ipath "*$fpterm*" -o -ipath "*$fpterm2*" )
(a 또는 b 또는 c) 및 (d 또는 e 또는 f) 형식으로 찾기를 수행하려면 괄호 안의 선택적 매개변수를 사용하십시오.
._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
./dm-1/mb_max_to_scan
./dm-1/warning_count
./dm-0/mb_max_to_scan
./dm-0/warning_count
./sda1/mb_max_to_scan
./sda1/warning_count
그러나 선택적 arg 배열이 비어 있으면 다른 조건 충족이 중지되고 파일을 전혀 찾지 못합니다.
._. fANDargs=()
._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
._.
빈 괄호는 문제를 일으킬 수 있습니다.
._. find . \( "${fargs[@]}" \) \( \) 2> /dev/null
._.
그러나 일반적으로 빈 arg 배열은 다른 조건이 충족되는 것을 방해하지 않습니다.
._. fANDargs=()
._. echo "${fANDargs[@]}"
._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
...
./sda1/mb_min_to_scan
./sda1/errors_count
./sda1/mb_max_to_scan
./sda1/msg_count
./sda1/warning_count
따라서 선택적 args 배열이 비어 있지 않은 경우에만 괄호를 추가할 수 있다면 이 명령이 작동할 수 있습니다.
하지만 조건부로 괄호를 추가하는 방법은 무엇입니까?
다음과 같이 배열에 괄호를 추가하면 작동하지 않는 것 같습니다.
._. fpterm=warning
._. fANDargs=()
._. [ ! -z $fpterm ] && fANDargs+=( '\(' -ipath "*$fpterm*" '\)' )
._. echo "${fANDargs[@]}"
\( -ipath *warning* \)
._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
._.
답변1
[ ! -z $fpterm ] && fANDargs+=( '\(' -ipath "*$fpterm*" '\)' )
여기에 큰따옴표가 있습니다. 레이어 하나만 사용해 보세요.
fANDargs+=( \( -ipath "*$fpterm*" \) ) # or
fANDargs+=( '(' -ipath "*$fpterm*" ')' ) # or with "(" and ")"
(또한 따옴표를 사용해야 합니다 [ ! -z "$fpterm" ]
)
일반적으로 명령에서 직접 단어를 사용하는 것과 똑같은 방식으로 배열 할당에 단어를 사용합니다. "${array[@]}"
당신처럼 따옴표를 사용하면 배열의 내용이 확장됩니다.추가 수정이 필요하지 않습니다..
(이것은 사람들이 종종 잘못 이해하는 부분입니다. 그들은 쉘이 확장 결과에 대한 따옴표를 처리할 것으로 기대하는 것 같습니다. 그렇지 않습니다. 여기서는 "일반적인" 프로그래밍 언어에 더 가깝습니다. 따옴표를 사용하여 제거하십시오. 분할+글로브의 문제.)
물론 여기서의 맥락은 find
그 자체로 보고 싶은 것은 대괄호를 있는 그대로(다른 인수로) 있다는 것입니다. 따옴표를 볼 필요는 없지만 볼 필요는 있습니다.껍데기괄호는 쉘 구문의 일부인 특수 문자이기 때문에 필요합니다. 따라서 따옴표 없이 사용할 수 있지만 somecmd { foo bar }
에서 사용해야 합니다 somecmd \( foo bar \)
.
그런데 GNU find는 빈 괄호 세트에 대해 경고합니다.
$ find . \( \)
find: invalid expression; empty parentheses are not allowed.
그리고 논리적으로 말하면 어쨌든 이상해 보입니다. 내 첫 번째 본능은 빈 대괄호가 false로 평가되어야 하며, 이로 인해 find \( whatever \) \( \)
항상 불일치가 발생한다는 것입니다. 그러나 이는 Busybox가 수행하는 것처럼 true로 해석될 수도 busybox find . \( \) -name '*.txt'
있으며 busybox find . -name '*.txt'
.