Trim space 仅从文档的开头和结尾开始,不触及内部 space 在 shell 脚本中使用 perl

Trim space ONLY from start & end of document without touching internal space using perl in shell script

我正在尝试 trim space 在文档的开头和结尾而不触及文件中的中间 space 在 bash 脚本中使用 perl

文件格式如下

<newline>
<space><newline>
<tab><newline>
<space><tab><newline>
START<newline><newline>
<space>INDENTED<newline><newline>
END<newline>
<space><tab><newline>
<tab><newline>
<space><newline>
<newline>

注意:<newline>\n<space> <tab>\t

所以原始文件看起来像


  
    
    
START


 INDENTED


END

    
    
 


我需要的文件内容是

START<newline><newline>
<space>INDENTED<newline><newline>
END

即像这样的最终文件

START


 INDENTED


END

我尝试在以下命令中同时使用它们,但它 trim 也是中间 space。它们都是 trim space 和整个文档的换行符,而不仅仅是从文档的开头开始

perl -pi -e 's/^\s*//gs' sample.txt
perl -pi -e 's/\A\s*//gs' sample.txt

两者都崩溃了所有内部space

START<newline>
INDENTED<newline>
END<newline>

我试过了。它折叠了换行符

perl -pi -e 's/\s*$//gs' sample.txt
perl -pi -e 's/\s*\Z//gs' sample.txt

两个折叠换行符

START<space>INDENTEDEND<newline>

这是我的假设

  1. \A 只匹配文档的开头 & \Z 匹配文档的结尾(相对于 ^ & $
  2. sgs 标志中确保整个文档被视为单行,换行符替换为字符 \n

我是 perl 新手。感谢有人能帮助我理解我哪里出错了

您可以在 slurp 模式下使用此 perl

perl -0777 -pe 's/^\s+|\R?\K\s+$//g' file

输出:

START

 INDENTED

END

详情:

  • -0777 启用 slurp 模式使 perl 读取完整文件
  • ^\s+ 匹配文件开头的 1+ 个空格
  • \R?\K\s+$:匹配一个换行符,后面跟着 1+ 个空格。使用 \K 我们在 \R 之后重置匹配,这样结束换行符就不会被删除

不是perl,但ed对编辑文件很有用:

$ printf '%s\n' '1,/START/-1d' '/END/+1,$d' w | ed -s sample.txt
$ cat sample.txt
START

 INDENTED

END

d 删除从第一行到匹配 START 之前的行以及从 END 之后的行范围内的所有内容到文件末尾,然后 w 将更改后的文件写入磁盘。


或类似的 perl 方法,它只打印您想要保留的范围内的行:

perl -i -ne 'print if /START/../END/' sample.txt

这是一个简短的 sed 版本:

sed -n '/START/,/END/p'

或使用否定逻辑:

sed '1,/START/{/START/!d}; /END/,${/END/!d}'