우분투 20.04에서 Bash를 사용하고 있습니다.
나는 파일을 가지고 있습니다 :
Hello hi 123
if a equals b
you
one abc two three four
dany uri four 123
sed
단 4단어로 된 줄을 찾아야 합니다 . 이것은 제가 작성한 코드인데 작동하지 않고 파일을 정확하게 인쇄합니다.
sed "/[a-Z0-9+]{4}/g" F1
답변1
이 문제는 다음과 같이 필드를 쉽게 계산할 수 있는 도구로 해결되어야 합니다 awk
.
$ awk 'NF == 4' file
if a equals b
dany uri four 123
이는 현재 레코드의 필드 수를 보유하는 NF
특수 변수를 사용합니다. awk
기본적으로 레코드는 한 줄이고 필드는 줄의 시작이나 끝 부분에 있는 빈 필드를 제외하고 하나 이상의 공백 문자(탭 또는 공백)로 구분된 하위 문자열입니다. 위의 짧은 프로그램은 awk
정확히 4개의 필드를 포함하는 모든 라인을 출력합니다.
를 사용하는 경우 sed
공백으로 구분된 하위 문자열을 일치시켜야 합니다.
sed
기본 정규식은 기본적으로 사용되며 표시되는 표현식은 확장 정규식 수정자인 을 사용 합니다 {4}
. 기본 정규식에 해당하는 내용이 작성됩니다 \{4\}
. 또한 유효하지 않은 문자 범위를 사용하고 a-Z
있으며 사용하려는 문자 클래스는 로 작성하는 것이 더 좋습니다 [[:alnum:]]
. 즉, 모든 영숫자 문자와 일치하는 것입니다(include가 +
철자가 틀린 것으로 가정). "예약된 공간"에서 데이터를 가져오기 위한 후행 g
명령이 잘못된 것 같습니다.
여기서 나의 일반적인 아이디어는 각 단어(공백이 아닌 문자 하나 이상)를 단일 x
단어로 압축한 다음 모든 공백 문자(탭 또는 공백)를 제거하는 것입니다. 결과 문자열이 이면 xxxx
원래 줄을 인쇄합니다(그렇지 않으면 줄을 삭제하고 즉시 다음 루프를 시작합니다).
sed -e h \
-e 's/[^[:blank:]]\{1,\}/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file
여기서 원래 줄은 먼저 를 사용하여 "예약된 공간"에 저장한 h
다음 인쇄해야 할 경우 다시 꺼내어 g
마지막으로 사용합니다. 두 번째부터 마지막 줄 까지 d
의 명령이 실행되면 g
마지막 줄은 고려되지 않습니다.
또는 확장 정규식을 사용하세요.
sed -E -e h \
-e 's/[^[:blank:]]+/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file
시험:
$ sed -e h \
> -e 's/[^[:blank:]]\{1,\}/x/g' \
> -e 's/[^x]//g' \
> -e '/^xxxx$/!d' \
> -e g file
if a equals b
dany uri four 123
[[:alnum:]]
(공백이 아닌) 대신 클래스로 단어 문자를 정의하려면 [^[:blank:]]
위 표현식을 [^[:blank:]]
로 변경하세요. [[:alnum:]]
차이점은 GNU/Linux
or 와 같은 문자열은 Unix-system
각 단어가 아닌 두 단어로 처리된다는 것입니다.
답변2
GNU 사용 sed
:
$ sed -E '/^\s*(\w+\s+){3}\w+\s*$/!d' infile
if a equals b
dany uri four 123
POSIXly 다음과 같이 작성할 수 있습니다.
sed '/^[[:space:]]*\([_[:alnum:]][_[:alnum:]]*[[:space:]][[:space:]]*\)\{3\}[_[:alnum:]][_[:alnum:]]*[[:space:]]*$/!d' infile
답변3
우리가 만든 정규식을 활용 하여 GNU sed
선택적 선행 공백을 찾은 다음 정확히 4쌍의 비공백 + 공백, 패턴 공간의 끝을 찾습니다.
$ sed -nE 'G;/^\s*(\S+\s+){4}$/P' F1
또는,
sed -nE '
s/\S+/&/4;T # 3 or less chunks
s//&/5;t # 5 or more chunks
p # exactly 4 chunks
' F1
sed -E '
s/\S+/&/5; td # 5 or more chunks
s//&/4; t # exactly 4 chunks
:d;d # 3 or less or 5 or more
' F1
답변4
분명히 awk
이 사용 사례에 대한 더 나은 도구이지만 이것이 OP가 지정한 것입니다 sed
.
GNU를 사용하면 sed
다양한 솔루션이 가능합니다 . 예약된 공간을 사용하는 것은 다음과 같습니다.
$ cat -A file
Hello hi 123$
if a equals b$
you$
one abc two three four$
dany uri four 123$
one two three four$
five six ^Iseven eight $
$ sed -e 'h; s/^\s*//; s/\s*$//' -nre '/^\w+(\W+\w+){3}$/{g;p}' file
if a equals b
dany uri four 123
one two three four
five six seven eight
$
명령은 sed
다음과 같이 단순화될 수 있습니다.
$ sed -nr '/^\s*(\w+)(\W+\w+){3}\s*$/p' file
대신 POSIX 문자 클래스를 사용하는 이전 명령 sed
의 이식성이 더 높은 또 다른 버전 은 다음과 같습니다 .-E
-r
$ sed -En '/^[[:blank:]]*[[:alnum:]]+([[:blank:]]+[[:alnum:]]+){3}[[:blank:]]*$/p' file