![배열의 반복 요소(첫 번째 요소와 마지막 요소 제외)](https://linux55.com/image/142262/%EB%B0%B0%EC%97%B4%EC%9D%98%20%EB%B0%98%EB%B3%B5%20%EC%9A%94%EC%86%8C(%EC%B2%AB%20%EB%B2%88%EC%A7%B8%20%EC%9A%94%EC%86%8C%EC%99%80%20%EB%A7%88%EC%A7%80%EB%A7%89%20%EC%9A%94%EC%86%8C%20%EC%A0%9C%EC%99%B8).png)
배열이 있고 첫 번째 요소와 마지막 요소를 제외한 모든 요소를 반복하고 싶습니다.
예를 들어, 배열에 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
배열의 요소에 액세스하는 데 사용됩니다. 마지막으로 원래 배열은 결과를 포함하도록 업데이트됩니다.
내가 대신 이걸 해반품함수에서만 종료 상태를 반환할 수 있으므로 배열입니다. 또 다른 방법은 입력 배열의 두 이름을 전달하는 것입니다.그리고배열을 출력하고 함수의 두 이름을 모두 사용하여 변수를 참조합니다.
또는 함수의 값을 echo
OR한 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>