두 개의 find 명령 출력을 단일 변수에 추가하지만 파일에는 추가하지 않습니다.

두 개의 find 명령 출력을 단일 변수에 추가하지만 파일에는 추가하지 않습니다.

내 사용 사례는 두 개의 찾기 명령을 파일 대신 단일 변수로 출력하는 것입니다. 시도하고 작동하지 않는다는 것을 알게 된 몇 가지 사항은 다음과 같습니다.

실제 find명령은 다음과 같습니다.

find /opt/apps -xdev -type f -name '*vunn*-2*jar'
find /opt/apps -xdev -type f -name '*robj-2*jar'

옵션 1: 두 번째 출력만 저장합니다.

temp_jars=$(find /opt/apps -xdev -type f -name '*vunn*-2*jar')
temp_jars=$(find /opt/apps -xdev -type f -name '*robj*-2*jar')

옵션 2: 기준인용하다, 아래에서 시도했지만 첫 번째 명령만 실행되었습니다.

export temp_jars="$(find /opt/apps -xdev -type f -name '*vunn*-2*jar' && find /opt/apps -xdev -type f -name '*robj-2*jar')"

당신의 도움을 주셔서 감사합니다.

답변1

이를 수행하는 방법에는 여러 가지가 있습니다. 귀하의 경우 가장 쉬운 방법은 명령을 결합 find하고 전체 문제를 피하는 것입니다.

temp_jars=$(find /opt/apps -xdev -type f \( -name '*vunn*-2*jar' -o -name '*robj-2*jar' \)

실제로 여러 명령이 필요한 다른 경우에는 명령을 개별적으로 실행한 다음추가의덮어쓰는 대신 변수로 출력합니다(이것은 실행한 다음 수행하는 작업이며 foo=barfoo=baz번째 변수를 덮어쓰기 때문에 마지막 변수만 유지합니다).

$ var=$(echo foo)
$ var="$var $(echo bar)"
$ echo "$var"
foo bar

또는 한 단계로 수행합니다.

$ var="$(echo foo; echo bar)"
$ echo "$var"
foo
bar

&&( 대신)을 사용한 방법은 ;첫 번째 명령이 성공한 경우에만 두 번째 명령이 실행된다는 의미입니다. 따라서 find어떤 이유로든 첫 번째 명령이 실패하면( find결과가 없으면 해당 명령은 실패하고 오류만 발생합니다.) 예를 들어 존재하지 않는 디렉토리에서 검색하도록 지시하면 두 번째 디렉토리는 실행되지 않습니다. 귀하의 경우에는 &&실패한 이유가 없습니다 . 작동하지 않는 것이 확실합니까?

답변2

여러 값을 저장하려면 스칼라 변수 대신 배열을 사용하십시오.

readarray -td '' temp_jars < <(
  find /opt/apps -xdev -type f -name '*vunn*-2*jar' -print0
  find /opt/apps -xdev -type f -name '*robj*-2*jar' -print0
)

( -d여기서 NUL을 구분 기호로 지정하려면 bash 4.4 이상이 필요합니다.)

그러나 @terdon이 이미 말했듯 vunn이 이러한 항목을 앞에 나열하는 것이 중요하지 않은 한 단일 명령으로 이 작업을 수행할 수 있습니다.robjfind

그런 다음 파일 이름을 일부 명령에 별도의 인수로 전달하려면 "${temp_jars[@]}".

예를 들어:

printf ' * %s\n' "${temp_jars[@]}"

배열 변수는 사용할 수 없습니다 export. 환경 변수는 단지 스칼라일 뿐입니다. bash 변수는 NUL 바이트를 포함할 수 없으므로 파일 경로 목록(그 자체는 null이 아닌 바이트의 (null이 아닌) 시퀀스로 구성될 수 있음) 인코딩 형식을 사용하지 않는 한 안정적으로 보관할 수 없습니다. 인용하다.

또한 프로세스 교체로 시작된 서브셸의 종료 상태(이 경우 find두 번째 명령의 종료 상태)가 손실되지만 최신 버전 bash에서는 wait "$!"; status=$?.

readarray(일명, mapfile's와 아무 관련이 없고 실제로는 그렇지 않지만zshmapfile매핑) bash구체적이다. 여기서 동등한 것은 다음 zsh과 같습니다:

temp_jars=(
  ${(0)"$(
    find /opt/apps -xdev -type f -name '*vunn*-2*jar' -print0
    find /opt/apps -xdev -type f -name '*robj*-2*jar' -print0
  )"}
)

0NUL을 분할하려면 매개변수 확장 플래그를 사용하십시오 . 이 경우 종료 상태는 $?평소와 같이 직접 사용할 수 있습니다.

배열에 요소를 추가하려면 sum 에서 다음을 수행할 수 있습니다 zsh.bash

temp_jars+=(more elements)

Bash를 사용하면 이 옵션을 사용하여 값을 저장할 배열의 인덱스를 지정할 readarray수 있습니다 .-O

다음을 사용하여 배열의 마지막 할당 인덱스를 얻을 수 있습니다.

indexes=("${!temp_jars[@]}"); last_index=${indexes[-1]}

그런 다음 다음을 사용하십시오.

readarray -td '' -O "$((last_index + 1))" temp_jars < <(find ... -print0)

배열이 처음에 희소하지 않은 경우(Straight before 이후의 경우처럼 readarray) 다음과 같이 단순화할 수 있습니다.

readarray -td '' -O "${#temp_jars[@]}" temp_jars < <(find ... -print0)

여기서는 ${#temp_jars[@]}배열의 요소 수입니다(배열 인덱스가 1 대신 0에서 시작하므로 배열이 희박하지 않은 경우 1에 마지막으로 할당된 인덱스를 더한 값에 해당).

대부분 zsh의 다른 쉘과 마찬가지로 배열은 희박하지 않으며 인덱싱은 $#temp_jars요소 수와 마지막 할당 인덱스로 시작됩니다.

관련 정보