eka*_*sis 5 sed awk perl text-processing
testing on Linux [Remove white space] testing on Linux
Run Code Online (Sandbox Code Playgroud)
testing on Linux [Removewhitespace] testing on Linux
Run Code Online (Sandbox Code Playgroud)
那么,我们如何才能删除括号之间的所有空白并实现给定的输出?
如果[,]是平衡的而不是嵌套的,你可以awk像这样使用 GNU :
gawk -v RS='[][]' '
NR % 2 == 0 {gsub(/\s/,"")}
{printf "%s", $0 RT}'
Run Code Online (Sandbox Code Playgroud)
那就是使用[and]作为记录分隔符而不是换行符,并且只删除每隔一条记录上的空格。
使用 sed,还有一个额外要求,即里面没有换行符[...]:
sed -e :1 -e 's/\(\[[^]]*\)[[:space:]]/\1/g;t1'
Run Code Online (Sandbox Code Playgroud)
如果它们是平衡的,但可能像 in 那样嵌套blah [blih [1] bluh] asd,那么您可以使用perl的递归正则表达式运算符,例如:
perl -0777 -pe 's{(\[((?:(?>[^][]+)|(?1))*)\])}{$&=~s/\s//rsg}gse'
Run Code Online (Sandbox Code Playgroud)
另一种可以扩展到非常大的文件的方法是使用(?{...})perl regexp 运算符来跟踪括号深度,如下所示:
perl -pe 'BEGIN{$/=\8192}s{((?:\[(?{$l++})|\](?{$l--})|[^][\s]+)*)(\s+)}
{"$1".($l>0?"":$2)}gse'
Run Code Online (Sandbox Code Playgroud)
实际上,您还可以一次处理输入一个字符,例如:
perl -pe 'BEGIN{$/=\1}if($l>0&&/\s/){$_=""}elsif($_ eq"["){$l++}elsif($_ eq"]"){$l--}'
Run Code Online (Sandbox Code Playgroud)
这种方法可以用 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}'
Run Code Online (Sandbox Code Playgroud)
使用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'
Run Code Online (Sandbox Code Playgroud)
被视为ASCII 字符集中任何水平(SPC、TAB)或垂直(NL、CR、VT、FF...)间距字符上方的空白。根据您的语言环境,其他人可能会被包括在内。