나는
grep -oE '[^ ]+$' pathname
awk 또는 sed. 누군가 대답하고 설명할 수 있다면 좋을 것 같습니다. 감사해요.
답변1
awk
예, superset 이므로 다음 grep
에서도 grep
패턴을 사용할 수 있습니다 awk
.
awk '{match($0, "[^ ]+$"); if (RSTART > 0) print substr($0, RSTART, RLENGTH)}'
답변2
grep
먼저 명령이 수행하는 작업을 검토해 보겠습니다 .
- 전체 줄이 아닌 일치하는 부분 만
-o
출력하도록 지시합니다.grep
- 이
-E
플래그를 사용하면 확장 정규식을 사용할 수 있습니다. '[^ ]+$'
줄 끝에서 한 번 이상 반복되는 공백이 아닌 문자(기본적으로 줄 끝의 단어)와 일치합니다.
테스트 실행:
$ cat input.txt
to be or not to be
that is the question
$ grep -oE '[^ ]+$' input.txt
be
question
이제 에서 동일한 작업을 어떻게 수행할 수 있습니까 awk
? awk
기본적으로 공백으로 구분된 항목의 각 줄에서 작동한다는 점을 고려하면 쉽습니다 awk
(단어라고 부르겠습니다. 필드라고 부르겠습니다). 따라서 $NF
awk를 사용하여 인쇄할 수 있습니다. NF
필드 수를 포함하는 변수를 가져와 특정 필드를 참조하는 것으로 처리합니다. 하지만 이 grep
명령은 비어 있지 않은 줄에만 일치합니다. 즉, 거기에 최소한 하나의 단어가 있습니다. 따라서 조건이 필요합니다 awk
. NF
필드 수가 0보다 큰 행에서만 작동합니다.
awk 'NF{print $NF}' input.txt
GNU awk는 적어도 확장 정규식을 지원한다는 점에 유의해야 합니다. (저는 다른 정규식에 대해 잘 알지 못하므로 다른 정규식에 대해서는 언급하지 않겠습니다.) 따라서 cuonglm의 답변을 기반으로 변형을 작성할 수도 있습니다.
$ awk '{if(match($0,/[^ ]+$/)) print $NF}' input.txt
be
question
GNU를 사용하면 sed
확장 정규식을 사용할 수도 있습니다. 이를 위해서는 -r
플래그가 필요하지만 단순히 동일한 정규식을 사용할 수는 없습니다. 역참조가 필요합니다 \1
.
$ cat input.txt
to be or not to be
that is the question
blah
$ sed -r -e 's/^.* ([^ ]+)$/\1/' input.txt
be
question
blah
다음과 같은 기본 정규식을 사용하여 원하는 결과를 얻을 수 있습니다.
$ cat input.txt
to be or not to be
that is the question
blah
$ sed 's/^.* \([^ ].*\)$/\1/' input.txt
be
question
blah
자세한 내용은 다음 게시물을 참조하세요.
답변3
전혀:
awk 'NF>0 {print $NF}' ## fails with end of line spaces; \thnaks{cuonglm}
awk '/[^ ]$/ {print $NF}' ## fails with tabs in lasts field; \thanks{Terdon}
awk -F ' +' '$NF {print $NF}' ## too tricky
awk 'match($0,/[^ ]+$/,a){print a[0]}' ## follows def. of grep -o
sed에서:
sed -nr 's/(|.* )([^ ]+)$/\2/p'
\감사합니다{cuonglm}
그리고 (왜 안되죠?) Perl에서는
perl -nlE '/([^ ]+)$/ and say $1'
답변4
이것은 grep으로 수행하려는 작업과 sed에 해당합니다.
# there is a space n a tab in the [...]
sed -ne '/[^ ]$/s/.*[ ]//p'
# this makes the code intent visually unambiguous
TAB=`echo 'x' | tr 'x' '\011'`; # tab
SPC=`echo 'x' | tr 'x' '\040'`; # space
h="[$SPC$TAB]"; # whitespace
S="[^$TAB$SPC]"; # nonwhitespace
sed -ne "/$S\$/s/.*$h//p"
sed -ne "s/.*$h\($S$S*\)\$/\1/p"