두 번째 목록에서 목록 요소의 첫 번째 항목을 찾는 Bash 스크립트

두 번째 목록에서 목록 요소의 첫 번째 항목을 찾는 Bash 스크립트

val_str="11 22 33"필요한 경우 배열로 저장할 수 있는 숫자 목록(중복 없음)이 있습니다 val_arr=(11 22 33). 예를 들면 다음과 같습니다.

탭으로 구분된 파일의 필드에서 가져온 두 번째 숫자 목록이 있습니다. 필요한 경우 이를 사용할 수 있습니다 awk. 다음은 장난감 데이터입니다.

echo -e "66\n55\n99\n33\n11\n88\n77\n22\n33" > list

val_arr에 나타나는 첫 번째 요소의 값을 찾고 싶습니다 list. 의 일부 요소는 val_arr에 나타나지 않을 수 있습니다 list. 아래 코드는 의 모든 요소가 val_arr에 있으면 작동하지만, list그렇지 않은 경우에는 실패합니다(예: if ) val_arr=(11 44 22 33).

val_arr=(11 22 33)
echo -e "66\n55\n99\n33\n11\n88\n77\n22\n33" > list
pos_arr=()
for i in ${!val_arr[@]}; do
    list_pos=$(grep -nm 1 ${val_arr[$i]} list | cut -f1 -d:)
    pos_arr+=( ${list_pos} )
done

pos1=$(echo ${pos_arr[@]} | tr ' ' '\n' | awk 'NR==1 {min=$0} NR>1 && $1<min {min=$1; pos=NR} END {print pos}')
pos0=$(( pos1 - 1 ))
val=${val_arr[$pos0]}

두 경우 모두 스크립트 val_arr=(11 22 33)가 .val_arr=(11 44 22 33)33

내 질문은 다음과 같습니다

  1. 더 좋은 방법이 있나요?
  2. 이 코드를 누락된 값에 대해 강력하게 만드는 방법이 있습니까( val_arry모든 값을 with 끝에 추가하는 것보다 더 우아함)?listecho ${pos_arr[@]} | tr ' ' '\n' >> list

감사해요!

awkPS 위 코드를 제공한 @Adrian Frühwirth에게 감사드립니다 .https://stackoverflow.com/questions/16610162/bash-return-position-of-the-smallest-entry-in-an-array

답변1

val_arrgrep 패턴이나 표현식 목록으로 바꾸는 것은 어떻습니까?

$ echo "${val_arr[@]/#/-e}"
-e11 -e44 -e22 -e33

직접 사용하나요?

$ grep -wFm1 "${val_arr[@]/#/-e}" list
33

답변2

나는 단지 grep배열을 사용하여 문자열로 변환합니다.

#!/bin/bash
val_arr=(11 22 33)

grep_string=$(tr ' ' '|' <<<"${val_arr[@]}")

first_found=$(grep -wEm1 "$grep_string" list);
if [[ -z $first_found ]]; then
  echo "None of the numbers were found"
else
  echo "Found: $first_found"
fi

tr명령은 배열을 다음으로 구분된 요소 목록으로 변환합니다 |.

$ grep_string=$(tr ' ' '|' <<<"${val_arr[@]}")
$ echo $grep_string 
11|22|33

그런 다음 grep -E사용되는 옵션은 다음과 같습니다.

  • -E|: "OR"을 나타내는 데 사용할 수 있도록 확장 정규식을 활성화합니다 .
  • -w: 단어 전체만 일치하므로 3일치하지 않습니다 33. -x입력에 따라 (전체 줄 일치)를 사용할 수도 있습니다 .
  • -m1: 첫 번째 게임 후 중지합니다.

파일의 위치도 필요한 경우 -n줄 번호도 인쇄되도록 추가하세요.

관련 정보