배열의 반복 요소(첫 번째 요소와 마지막 요소 제외)

배열의 반복 요소(첫 번째 요소와 마지막 요소 제외)

배열이 있고 첫 번째 요소와 마지막 요소를 제외한 모든 요소를 ​​반복하고 싶습니다.

예를 들어, 배열에 5개의 요소가 있는 경우 1 2 3 4 5반복 후 해당 요소는 이어야 합니다 1 2 2 3 3 4 4 5.

내 bash 명령은 다음과 같습니다

$ newarr=("${myarr[0]}")
$ for i in $(seq 1 $((${#myarr[@]}-2))) ; do newarr+=( "${myarr[i]}" "${myarr[i]}"); done
$ newarr+=("${myarr[-1]}")

내 것보다 더 명확한 방법이 있습니까?

myarr또한 이것을 인수를 받아 반환하는 함수 로 래핑하는 방법도 알고 싶습니다 newarr. (이러한 함수를 만든 후 각 요소가 파일에 행을 저장하도록 파일에서 배열을 읽은 다음 배열에서 함수를 호출합니다. 이러한 함수를 만드는 것이 좋은 접근 방식이 아닌 경우 알려 주시기 바랍니다. )

감사해요.

답변1

작업 수를 약간 줄이고 다음 호출을 건너뛸 수 있습니다 seq.

for (( i = 1; i < ${#myarr[@]} - 1; ++i )); do
    newarr+=( "${myarr[i]}" "${myarr[i]}" )
done
newarr=( "${myarr[0]}" "${newarr[@]}" "${myarr[-1]}" )

newarr이는 처음부터 비어 있다고 가정합니다 . unset newarry그렇지 않다면 먼저 하십시오.

함수로서(이것은 전달된 배열을 수정합니다):

dup_interal_items () {
    typeset -n arr=$1
    local tmparr

    for (( i = 1; i < ${#arr[@]} - 1; ++i )); do
        tmparr+=( "${arr[i]}" "${arr[i]}" )
    done
    arr=( "${arr[0]}" "${tmparr[@]}" "${arr[-1]}" )
}

이것이름배열의 값은 함수에 전달되고 이름 참조 변수는 arr배열의 요소에 액세스하는 데 사용됩니다. 마지막으로 원래 배열은 결과를 포함하도록 업데이트됩니다.

내가 대신 이걸 해반품함수에서만 종료 상태를 반환할 수 있으므로 배열입니다. 또 다른 방법은 입력 배열의 두 이름을 전달하는 것입니다.그리고배열을 출력하고 함수의 두 이름을 모두 사용하여 변수를 참조합니다.

또는 함수의 값을 echoOR한 printf다음(이 경우 새 배열을 전혀 구성할 필요가 없음) 기본 코드에서 해당 데이터를 구문 분석할 수 있습니다. 그런 다음 명령 대체 내에서 함수를 호출해야 합니다.

참고하시기 바랍니다할 수 없다arr이 함수는 사용되는 특정 이름 범위 지정 규칙으로 인해 호출되는 배열과 함께 호출됩니다 bash. 이것이 문제인 경우 arr함수의 변수 이름을 바꿔야 할 수도 있습니다.

시험:

$ myarr=( 1 2 3 "here we go" )
$ dup_interal_items myarr
$ printf 'Element: %s\n' "${myarr[@]}"
Element: 1
Element: 2
Element: 2
Element: 3
Element: 3
Element: here we go

파일의 첫 번째 줄과 마지막 줄을 제외한 모든 줄을 복사하려면 다음을 수행하세요.

sed -e '1b' -e '$b' -e 'p' <file

스크립트가 sed첫 번째 줄이나 마지막 줄에 있는 경우 스크립트는 끝(암시적 print 문이 있는 경우)으로 분기되지만 다른 모든 줄은 인쇄됩니다(따라서 다른 모든 줄은 명시적으로 마지막 줄에 의해 인쇄되고 p암시적으로 인쇄됩니다).

또는 don_crissti가 제공한 것입니다.

sed 'p;1d;$d' <file

각 줄을 명시적으로 인쇄한 다음 첫 번째와 마지막 줄의 루프를 종료하지만 다른 모든 줄은 암시적으로 인쇄합니다(두 번째).

메모리에 한 줄 이상을 저장하지 않는 동등한 프로그램은 awk작성하기가 간단하지 않습니다.

답변2

또한 시도해 보십시오 - 기능이 필요하지 않습니다 -

$ ARR=(1 2 3 4 5)
$ IFS=$'\n\t '
$ readarray NEWARR < <(echo "${ARR[*]}" | sed '1!p; $d')
$ echo ${NEWARR[@]}
1 2 2 3 3 4 4 5

심지어

NEWARR=($(printf "%s\n" ${ARR[@]} | sed '1!p; $d'))

답변3

줄바꿈을 허용하는 솔루션:

#!/bin/bash
arr=( 1 2 "3 3" $'41\n42' 5 )

readarray -t -d $'\0' newarray < <(printf '%s\0' "${arr[@]}" | sed -z '1!p; $d')

printf '<%s>\n' "${newarr[@]}"

다음으로 실행:

$ ./script
<1>
<2>
<2>
<3 3>
<3 3>
<41
42>
<41
42>
<5>

관련 정보