"," 뒤의 모든 내용을 삭제하려면 awk를 사용하세요.

"," 뒤의 모든 내용을 삭제하려면 awk를 사용하세요.

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나중에 입력 파일을 처리하는 데 도움이 됩니다.

관련 정보