올바르게 이해했다면 출력의 기본 구분 기호는 다음 awk
과 같습니다.공간.
그러나 다음 스크립트는 예상대로 작동하지 않습니다. 다음의 출력을 awk
배열로 구문 분석할 수 없습니다.
#!/bin/bash
echo "------ with input string from awk ------"
ALL_TTY_OWNERS_STR=$(ls -l /dev | grep tty | awk '{print $3}')
read -r -a ALL_TTY_OWNERS_ARRAY <<< "$ALL_TTY_OWNERS_STR"
echo "${#ALL_TTY_OWNERS_ARRAY[@]}" # This says 1
echo "${ALL_TTY_OWNERS_ARRAY[0]}" # "root", as expected
echo "${ALL_TTY_OWNERS_ARRAY[1]}" # empty string, expected "root"
echo "${ALL_TTY_OWNERS_ARRAY[2]}" # empty string, expected "root"
echo "------ with my manually created input string ------"
ALL_TTY_OWNERS_STR="root root root" # only for testing
read -r -a ALL_TTY_OWNERS_ARRAY <<< "$ALL_TTY_OWNERS_STR"
echo "${#ALL_TTY_OWNERS_ARRAY[@]}" # 3, as expected
echo "${ALL_TTY_OWNERS_ARRAY[0]}" # "root", as expected
echo "${ALL_TTY_OWNERS_ARRAY[1]}" # "root", as expected
echo "${ALL_TTY_OWNERS_ARRAY[2]}" # "root", as expected
with 의 출력을 예상대로 구문 분석할 수 없는 이유는 무엇입니까 awk
?read
답변1
그것은 관하여대지분할기.
당신은 정의해야기록구분 기호는 각 문자열을 단일 문자열에 넣습니다. 사용 ORS
매개변수:
ls -l /dev | grep tty | awk 'BEGIN { ORS=" " }; {print $3}'
그것이 없으면 출력은 다음과 같습니다:
root
root
root
etc...
ALL_TTY_OWNERS_STR
변수를 정의할 때그냥 먼저 넣어두세요배열의 첫 번째 요소에 있는 출력 문자열입니다. 따라서 귀하의 배열에는 단 하나의 요소만 포함됩니다. 이는 정확히 귀하가 얻는 것입니다.
답변2
출력의 기본 필드 구분 기호는 공백입니다. 그러나 레코드 구분 기호는 새로운 줄입니다. 줄바꿈으로 구분된 ALL_TTY_OWNERS_STR
여러 개의 s를 포함합니다 .root
$ printf "%q\n" "$ALL_TTY_OWNERS_STR"
$'root\nroot\nroot\n....
기본적으로 read
첫 번째 개행 문자를 읽습니다.
모든 사용자를 에 포함시키려면 ALL_TTY_OWNERS_ARRAY
다음을 수행하는 것이 더 간단할 수 있습니다.
ALL_TTY_OWNERS_ARRAY=( $(stat -c '%U' /dev/*tty*) )
답변3
read -a array
레코드의 모든 단어를 읽습니다 array
.
전체 입력의 모든 단어를 읽으려면 -d ''
NUL 문자를 레코드 구분 기호로 사용하거나 -d :
( :
사용자 이름에 나타날 수 없는) 입력에 나타나지 않는 레코드 구분 기호를 사용하십시오.
IFS=$'\n' read -rd '' -a array < <(ls -Ll /dev | awk '/tty/{print $3}')
(여기에서는 기호 링크가 사용되어 -L
기호 링크가 아닌 장치의 소유권을 반환합니다.)
또는 readarray
각각 에 대해철사배열에 저장될 입력입니다.
readarray -t array < <(ls -Ll /dev | awk '/tty/{print $3}')
또는 분할+glob 연산자를 사용할 수 있습니다.
set -o noglob # disable glob part
IFS=$'\n' # split on newline
array=($(ls -Ll /dev | awk '/tty/{print $3}')) # invoke split+glob by leaving
# the $(...) unquoted.
사용자 및 그룹 이름, 파일 이름(생략된 경우 심볼릭 링크 대상 )을 포함한 의 전체 출력이 포함 됩니다 tty
. 파일 이름만 고려하고 싶다면 다음을 수행할 수 있습니다.ls -Ll
-L
ls -Lld /dev/*tty* | awk '{print $3}'
대신에.
이를 통해 zsh
다음을 수행할 수 있습니다.
zmodload zsh/stat
stat -s -A array +uid /dev/*tty*
(이는 공백이 포함된 사용자 이름에도 도움이 됩니다.)
답변4
after 변수를 인용하지 않으면 <<<
줄 바꿈은 예상한 공백이 되며 결과는 모두 한 줄에 표시됩니다.
read -r -a ALL_TTY_OWNERS_ARRAY <<< $ALL_TTY_OWNERS_STR