나는 다음 명령을 발견했습니다.
ls -l <directory> \
| tail -n +2 \
| sed 's/\s\s*/ /g' \
| cut -d ' ' -f 3 \
| sort \
| uniq -c
\s\s*
이 sed
옵션 의 목적을 잘 모르겠습니다 .
나는 그것이 \s
공백을 의미한다는 것을 알고 있습니다. 두 번째 공백이 \s
앞에 오기 때문에 *
두 번째 공백이 0번 이상 일치하게 됩니다.
sed
이는 입력 스트림에서 하나 이상의 연속 공백을 단일 공백으로 바꾸는 것을 의미합니까 ? 그렇다면 \s+
대신 사용하는 것은 어떨까요 \s\s*
?
답변1
\s
[[:space:]]
모든 종류의(가로 또는 세로) 공백 문자( 또는 다른 편집 명령으로 패턴 공간에 삽입 \s
된 경우 개행 문자)와 일치하는 POSIX 표현식을 작성하기 위한 GNU 정규 표현식 바로가기입니다 . sed
이 \s
표기법은 원래 Perl 정규식에서 유래되었습니다.
아래 코드 중 일부는 [[:space:]]
일반적으로 사용되지만실제로 의미 [[:blank:]]
, 공백과 탭만 일치합니다.
주문하다
sed 's/\s\s*/ /g'
하나 이상의 연속 공백을 단일 공백으로 바꾸고 현재 줄에 더 이상 일치하는 항목이 없을 때까지 교체를 반복합니다.
그렇습니다. 대신에 그것을 사용할 수도 있지만 s/\s+/ /g
,확장하다-E
(GNU) 기본 표현식 대신 정규 표현식을 사용하므로 명령에 다음을 추가해야 합니다 .
sed -E 's/\s+/ /g'
이제 비표준 옵션을 사용하십시오( -E
).그리고GNU 특정 정규 표현식( \s
). 표준을 준수하는 방식으로 명령을 작성하려면 다음을 사용해야 합니다.
sed 's/[[:space:]][[:space:]]*/ /g'
또는
sed 's/[[:space:]]\{1,\}/ /g'
의미는 \{1,\}
확장 정규식 수정자 및 ("하나 이상")과 동일합니다.+
{1,}
당신은 또한 사용할 수 있습니다
tr -s '[:blank:]' '[ *]'
비슷한 작업을 수행합니다. 즉, 모든 공백과 탭을 공백으로 변환하고 -s
연속 공백에 squeeze()를 단일 공백으로 실행합니다. 를 사용하면 [:space:]
바람직하지 않은 줄바꿈(캐리지 리턴, 수직 탭 등도 포함)도 대체됩니다.
또는 해당 파이프라인에서 sed
작업을 수행 tail
하고 다음을 사용할 수 있습니다.
ls -l dir | sed '1d; s/[[:space:]]\{1,\}/ /g' | cut -d ' ' -f 3 | sort | uniq -c
또는 다음을 사용하십시오 awk
.
ls -l dir | awk 'NR > 1 { count[$3]++ } END { for (user in count) print user, count[user] }'
(사용하면 awk
공간이 좁아질 걱정은 안하셔도 됩니다)