배열에서 데이터를 보다 효율적으로 추출하는 방법은 무엇입니까?

배열에서 데이터를 보다 효율적으로 추출하는 방법은 무엇입니까?

다음과 같은 데이터가 포함된 일부 텍스트 파일이 포함된 디렉터리가 있습니다. 이를 루프에서 읽고 각 줄을 배열에 넣습니다. 정확한 방법을 모르겠습니다. 더 좋은 방법을 아시는 분은 알려주세요.

Attack On Titan S03E20 720p WEB x264-URANiME[eztv] 6/17/2019 394 MB 114 37
Attack On Titan S003E020 WEB x264-URANiME Yesterday 172 MB 76 3
Attack On Titan S03E18 1080p WEB x264-URANiME 6/5/2019 1 GB 46 3
Attack On Titan S003E017 720p WEB x264-URANiME[eztv] 5/27/2019 555 MB 41 10
Attack On Titan s02E20 WEB x264-URANiME[eztv] 6/17/2019 171 MB 40 7
Attack On Titan S03e18 WEB x264-URANiME 6/3/2019 200 MB 23 3
Attack On Titan S03E16 720p WEB x264-URANiME[eztv] 5/20/2019 522 MB 23 3
Attack On Titan s03e19 WEB x264-URANiME Today 196 MB 20 0
Attack On Titan S03E14 720p WEB x264-URANiME[eztv] 5/6/2019 545 MB 19 2

각 줄의 요소는 토렌트 이름, 추가된 시간, 크기(MB/GB 확장자 포함), 시드, 리치 등의 탭으로 구분됩니다.

예를 들어 샘플 데이터의 첫 번째 행에 대해 언급된 요소는 다음과 같습니다.

torrent name: Attack On Titan S03E20 720p WEB x264-URANiME[eztv]
season number: 3
episode number: 20
added time: 6/17/2019
size: 394 MB
seed: 114
leech: 37

참고: 크기 숫자는 서로 다르지만(때로는 MB - 때로는 GB) 모두 MB로 만들어야 합니다. 어떻게 해야 합니까?

그래서 루프를 사용하여 배열의 각 행을 읽고 후속 단계에 필요한 각 부분을 꺼냈습니다!

for array_list in "${TORRENT_FILE_ARRAY[@]}"
do
    TORRENT_NAME=`echo "$array_list" | awk '{print $1}' FS="\t"`
    SEASON_NUMBER=`echo "$array_list" | awk '{print $1}' FS="\t" | awk '{print $4}' FS=" " | awk 'BEGIN {IGNORECASE = 1} {print $1}' FS="E" | sed "s/[Ss]//g" | sed 's/^0*//'`
    EPISODE_NUMBER=`echo "$array_list" | awk '{print $1}' FS="\t" | awk '{print $4}' FS=" " | awk 'BEGIN {IGNORECASE = 1} {print $2}' FS="E" | sed "s/[Ee]//g" | sed 's/^0*//' `
    FILE_SIZE=`echo "$array_list" | awk '{print $3}' FS="\t"`
    LEECH_NUMBER=`echo "$array_list" | awk '{print $4}' FS="\t"`
    SEED_NUBMBER=`echo "$array_list" | awk '{print $5}' FS="\t"`
    # echo $TORRENT_NAME
    # echo $FILE_SIZE
    # echo $LEECH_NUMBER
    # echo $SEED_NUBMBER
    # echo "SEASON_NUMBER:" $SEASON_NUMBER 
    # echo "EPISODE_NUMBER:" $EPISODE_NUMBER
done

각 변수를 읽은 후 앞서 언급한 각 요소의 배열에 해당 변수를 추가하고 싶습니다. 즉, 다음과 같습니다.

TORRENT_NAME[$x]=$extracted_TORRENT_NAME
FILE_SIZE[$x]=$extracted_FILE_SIZE
LEECH_NUMBER[$x]=$extracted_LEECH_NUMBER
SEED_NUBMBER[$x]=$extracted_SEED_NUBMBER 
SEASON_NUMBER[$x]=$extracted_SEASON_NUMBER
EPISODE_NUMBER[$x]=$extracted_EPISODE_NUMBER

루프에서 이러한 배열을 채우고 싶지만 데이터를 올바르게 캡처하는 방법과 데이터를 보다 효율적으로 캡처하기 위해 사용해야 하는 도구를 모르겠습니다!

또한 이 모든 것이 스크립트에 포함되어 있으므로 스크립트 파일 외에는 다른 파일을 생성하거나 소스 파일을 변경하는 것도 허용되지 않습니다!

답변1

죄송합니다. 질문의 나머지 부분을 이해하지 못합니다. 입력에서 실제로 원하는 필드를 분리하는 방법은 다음과 같습니다.

$ cat file
Attack On Titan S03E20  720p WEB x264-URANiME[eztv]     6/17/2019       394 MB  114     37

$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    name = $1
    sub(/ [^ ]+$/,"",name)
    sub(/.* [Ss]/,"",$1)
    sub(/[Ee]/,OFS,$1)
    $2 = $1
    $1 = name
    print
}

$ awk -f tst.awk file
Attack On Titan 03      20      6/17/2019       394 MB  114     37

가시성을 높이기 위해 입력/출력에서 탭 문자를 쉼표로 바꿉니다.

$ tr $'\t' ',' < file
Attack On Titan S03E20,720p WEB x264-URANiME[eztv],6/17/2019,394 MB,114,37

$ awk -f tst.awk file | tr $'\t' ','
Attack On Titan,03,20,6/17/2019,394 MB,114,37

그리고 awk 스크립트의 출력을 쉘 루프로 파이프하여 각 입력 행에 대해 여러 번 호출하는 대신 처음에 awk를 한 번 호출합니다.

awk -f tst.awk file |
while IFS=$'\t' read -r torrent_name season_name episode_number file_size leech_number seed_number; do
    whatever you need to do with creating directories and files
done

나는 쉘 루프가 당신이 하려는 모든 일에 적합할 것이라고 가정하고 있지만 잘 모르겠습니다.

관련 정보