var
다음을 포함하는 변수가 있습니다 .
XXXX YY ZZZZZ\n
aaa,bbb,ccc
내가 원하는 것은 aaa
두 번째 행뿐입니다. 나는 시도했다:
out=$(echo "$var" | awk 'NR==2{sub(",.*","")}' )
하지만 아무런 결과도 얻지 못합니다. FS로 사용해 보았지만 ,
구문을 제대로 얻을 수 없습니다. 저는 awk/regex 구문을 정말로 배우고 싶습니다.
인쇄가 아닌 다른 곳에서 "$out" 변수로 out을 사용하고 싶습니다.
답변1
정규 표현식을 원하지 않습니다. 요점은 awk
자동으로 행을 여러 필드로 분할하는 것이므로 필드 구분 기호를 로 설정 ,
하고 두 번째 행의 첫 번째 필드를 인쇄하면 됩니다.
$ printf '%s' "$var" | awk -F, 'NR==2{print $1}'
aaa
또는 쉘이 이를 지원하는 경우 <<<
:
$ awk -F, 'NR==2{print $1}' <<<"$var"
aaa
예상대로 사용 하지 않고 수동으로 수행하려면 awk
다음을 수행할 수 있습니다.
$ awk 'NR==2{sub(/,.*/,""); print}' <<<"$var"
aaa
awk
인쇄할 내용을 지정하지 않았기 때문에 아무 결과도 나오지 않습니다 .
답변2
${param#pattern}
또는 여기에서 ${param%%pattern}
표준 매개변수 확장 연산자를 사용할 수 있습니다.
NL='
'
out=${var#*"$NL"} # removes first line. Assumes there are at least 2
out=${out%%"$NL"*} # removes all but the first line
out=${out%%,*} # removes everything after the first ,
또는 bash
구체적으로 다음을 사용할 수 있습니다.
LC_ALL=C # needed to accept non-text
[[ $var =~ ^[^$'\n']*$'\n'([^,$'\n']*) ]]
out=${BASH_REMATCH[1]}
표준적으로 다음도 있습니다 expr
.
NL='
'
out=$(LC_ALL=C expr "x$var" : "[^$NL]*$NL\([^,$NL]*\)")
awk
접근 방식의 문제는 인쇄할 내용을 말하지 않는다는 것입니다 . awk
아무것도 인쇄되지 않으면 $(...)
내부 명령의 출력으로 확장될 때 변수에 아무것도 저장되지 않습니다. 또한 echo
임의의 데이터를 인쇄하는 데 사용할 수 없다는 점을 기억하십시오.
out=$(printf '%s\n' "$var" | awk 'NR == 2 {sub(",.*", ""); print}')
또는:
out=$(printf '%s\n' "$var" | awk -F, 'NR == 2 {print $1}')
1 빼기 후행 개행, 출력에 NUL 바이트가 포함된 경우 동작은 쉘 구현마다 다릅니다.
답변3
또 다른 옵션은 다음을 사용하는 것입니다 sed
.
sed -n 's/,.*$//p' <<< "$var"
- 이렇게 하면
s/../../
각 줄의 첫 번째 줄부터,
줄 끝까지( )까지의,.*$
모든 항목( )이 "없음"으로 바뀌고 해당 부분만 남습니다.앞으로첫 번째,
. - 이 옵션을 사용하면
-n
기본적으로 출력이 억제됩니다.p
프로그램 끝에 있는 명령은 여전히sed
"검색" 패턴이 발견된 행을 인쇄합니다. 이런 식으로 우리는 첫 번째 줄(없음)을 무시하고,
a가 실제로 발견되는 두 번째 줄만 처리합니다.,
평소와 같이 명령 대체를 통해 결과를 쉘 변수로 가져올 수 있습니다.
out=$(sed -n 's/,.*$//p' <<< "$var")
또는 여기 문자열을 이해하지 못하는 쉘에서,
out=$(printf '%s' "$var" | sed -n 's/,.*$//p')
극단적인 경우의 예를 포함하지 않았으므로 이를 수용하는 솔루션을 설계하기가 어렵습니다 . 현재 솔루션 에서는 첫 번째 필드를 추출하려는 $var
행이 하나만 있다고 가정합니다 .,
답변4
사용 sed
:
$ sed -n '2s/,.*//p' <<<"$var"
aaa
특히 대용량 파일을 읽는 경우 명령 실행의 두 번째 줄 뒤에 중단점을 설정하는 것이 좋습니다.
$ sed -n '2{s/,.*//p;q;}' infile
이는 q
나중에 입력 파일을 처리하는 데 도움이 됩니다.