grep
파일의 마지막 줄을 얻기 위해 파이프를 사용하여 bash에서 텍스트 줄을 읽은 다음 tail
줄의 처음 세 "단어"(예: 공백을 사용하여 구분)를 배열 요소로 분할하려고 합니다.
출력의 요소를 반복하려고 하면 for
제대로 작동하고 원하는 요소 목록을 얻습니다.
[] foo=$(grep select file.txt | tail -n 1)
[] echo $foo
0.47331 5.11188 13.1615 # select
[] for x in $foo; do echo $x; done
0.47331
5.11188
13.1615
#
select
그것이 바로 내가 하고 싶은 일이다!
그러나 처음 세 요소가 포함된 배열을 꺼내려고 하면 foo
작동하지 않습니다.
[] echo "${foo[@]:0:2}"
0.47331 5.11188 13.1615 # select 4.95294 13.5177
특히 이상한 점은 줄 끝의 마지막 두 값이 실제로는첫 번째select
file.txt
in (행의 처음 두 항목이 아니라 두 번째와 세 번째 항목!)을 포함하는 행 이므로 전혀 foo
포함 되어서는 안 됩니다.
마찬가지로 단순히 "단어"를 잘라내려고 하면 foo
이상한 결과가 나옵니다.
[] echo "${foo[0]}"
0.47331 5.11188 13.1615 # select
[] echo "${foo[1]}"
4.95294
(또 마지막 값은 있어서는 안되는 값인데, 제가 아는 한 에 있어도 foo
첫 번째 행의 두 번째 항목입니다 select
... file.txt
).
무슨 일이 일어나고 있는지, 내가 원하는 출력(배열)을 얻는 방법을 이해해야 합니다 0.47331 5.11188 13.1615
.
답변1
$foo
배열이 아니라 공백으로 구분된 여러 단어를 포함하는 문자열입니다. 배열이 되도록 하려면 다음과 같이 지정하십시오.
foo=( $(grep 'select' file.txt | tail -n 1) )
${foo[0]}
이제 또는 처음 세 요소를 로 참조할 수 있습니다 ${foo[@]:0:3}
.
${foo[@]}
여기에는 처음 세 개의 요소만 추출할 수 있는 것이 없기 때문에 여기에는 마지막 일치 행의 다섯 개 요소가 모두 포함 됩니다 . 원하는 경우 크기에 맞게 foo=("${foo[@]:0:3}")
잘라서 사용할 수 있습니다.${foo[@]}
또는 처음 세 요소만 포함하는 배열을 만들려면 awk
다음과 같이 사용할 수 있습니다.
foo=( $(awk '/select/ { a=$1; b=$2; c=$3 } END { print a,b,c }' file.txt) )
답변2
이렇게 하면 데이터를 변수로 읽는 것을 방지할 수 있습니다.
$ grep -F select file | tail -n 1 | cut -d ' ' -f 1-3
0.47331 5.11188 13.1615
의 배열에 값을 넣으려면 (또는 )을 bash
사용하십시오 .mapfile
readarray
$ mapfile -t arr < <( grep -F select file | tail -n 1 | cut -d ' ' -f 1-3 | tr ' ' '\n' )
$ printf 'arr: %s\n' "${arr[@]}"
arr: 0.47331
arr: 5.11188
arr: 13.1615
나는 tr
숫자 사이의 공백을 줄 바꿈으로 변경하는 데 사용합니다. 이렇게 하면 배열의 마지막 값 끝에 후행 개행 문자가 없어집니다.
어색한 +++ 파이프 대신 grep
분명히 사용할 tail
수 있습니다cut
tr
awk '/select/ { a=$1; b=$2; c=$3 } END { printf("%s\n%s\n%s\n", a, b, c) }'
또는 프로세스 교체와 유사한 것입니다 <(...)
.