입력하다
testing on Linux [Remove white space] testing on Linux
산출
testing on Linux [Removewhitespace] testing on Linux
그렇다면 대괄호 사이의 모든 공백을 어떻게 제거하고 주어진 출력을 얻을 수 있습니까?
답변1
[
가 균형을 이루고 중첩되지 않은 경우 다음과 같이 ]
GNU를 사용할 수 있습니다 .awk
gawk -v RS='[][]' '
NR % 2 == 0 {gsub(/\s/,"")}
{printf "%s", $0 RT}'
즉 , 개행 대신 [
및 레코드 구분 기호로 사용 하고 다른 모든 레코드에서 공백을 제거하십시오.]
sed를 사용할 때 추가 요구 사항은 내부에 개행 문자가 없어야 한다는 것입니다 [...]
.
sed -e :1 -e 's/\(\[[^]]*\)[[:space:]]/\1/g;t1'
균형이 잡혀 있지만 잠재적으로 다음과 같이 중첩된 경우 다음 과 같은 재귀 정규식 연산자를 blah [blih [1] bluh] asd
사용할 수 있습니다 .perl
perl -0777 -pe 's{(\[((?:(?>[^][]+)|(?1))*)\])}{$&=~s/\s//rsg}gse'
(?{...})
매우 큰 파일로 확장할 수 있는 또 다른 접근 방식은 다음과 같이 perl regexp 연산자를 사용하여 대괄호 깊이를 추적하는 것입니다 .
perl -pe 'BEGIN{$/=\8192}s{((?:\[(?{$l++})|\](?{$l--})|[^][\s]+)*)(\s+)}
{"$1".($l>0?"":$2)}gse'
실제로 다음과 같이 한 번에 한 문자씩 처리할 수도 있습니다.
perl -pe 'BEGIN{$/=\1}if($l>0&&/\s/){$_=""}elsif($_ eq"["){$l++}elsif($_ eq"]"){$l--}'
이 방법은 POSIX 도구를 사용하여 구현할 수 있습니다.
od -A n -vt u1 |
tr -cs 0-9 '[\n*]' |
awk 'BEGIN{b[32]=""; b[10]=""; b[12]=""} # add more for every blank
!NF{next}; l>0 && $0 in b {next}
$0 == "91" {l++}; $0 == "93" {l--}
{printf "%c", $0}'
사용하십시오 sed
(내부에 개행 문자가 없다고 가정 [...]
):
sed -e 's/_/_u/g;:1' -e 's/\(\[[^][]*\)\[\([^][]*\)]/\1_o\2_c/g;t1' \
-e :2 -e 's/\(\[[^]]*\)[[:space:]]/\1/g;t2' \
-e 's/_c/]/g;s/_o/[/g;s/_u/_/g'
고려되다공백ASCII 문자 집합의 가로(SPC, TAB) 또는 세로(NL, CR, VT, FF...) 간격 문자 위에 있습니다. 로케일에 따라 다른 항목이 포함될 수도 있습니다.
답변2
Perl 5.14 솔루션(더 짧고 읽기 쉽다고 생각합니다. 특히 파일에서 한 줄이 아닌 여러 줄로 형식을 지정하는 경우)
perl -pE 's{(\[ .*? \])}{$1 =~ y/ //dr}gex'
5.14에서는 정규식 엔진이 재진입 가능하기 때문에 이것이 가능합니다. 여기에서 확장하고 의견을 제시하세요.
s{
(\[ .*? \]) # search for [ ... ] block, capture (as $1)
}{
$1 =~ y/ //dr # delete spaces. you could add in other whitespace here, too
# d = delete; r = return result instead of modifying $1
}gex; # g = global (all [ ... ] blocks), e = replacement is perl code, x = allow extended regex
답변3
펄 솔루션:
perl -pe 's/(\[[^]]*?)\s([^][]*\])/$1$2/ while /\[[^]]*?\s[^][]*\]/'