从文件/管道中查找(并去除)常见的初始空格

从文件/管道中查找(并去除)常见的初始空格

我正在寻找一种方法来从文本流或文件中查找并删除常见的初始空格。我不想删除全部前导空格(这将是一个简单的sed 's/^[[:space:]]*//')。仅限所有人共同的金额但空行

例子:

printf '  some text\n\n   some more text\n' | the_awesome_command_or_script

应该打印

some text

 some more text

进步:

我知道可以使用awkshellwhile循环等工具首先循环所有行并计算初始空格,然后可以使用动态生成的 sed 命令删除空格。

用于计算空白的 awk 脚本可能类似于此

awk 'BEGIN { amount = 0 }
     /^[^[:space:]]/ { print 0; exit }
     /^$/{ next }
     /^[[:space:]]/ { amount = match($0, "[^[:space:]]") - 1 }
     END { print amount }'

但随后我需要一个临时文件,我的脚本将如下所示:

generate_some_text | cat > tempfile
amount=$(above_awk_script < tempfile)
sed "s/^[[:space:]]\{$amount\}//" < tempfile
rm tempfile

问题:

有没有更适合这项工作的工具?我可以修改脚本来删除临时文件吗?

现实:

我正在尝试改进我的 mailcap 条目,以满足text/html请求copiousoutput:目前是这样text/html; elinks -no-home -dump %s; nametemplate=%s.html; copiousoutput;,但正如您可能已经猜到的那样,我想删除一些初始空白。也许我只是想得太复杂了,有一个非常简单的解决方案吗?

答案1

由于它要么是所有空格,要么是所有制表符,您可以将其通过管道传输到

sed 'H;$!d;g;: m;/\n[^\n[:blank:]]/!s/\n[^\n]/\n/g;t m;s/.//'

那是gnu sed(我不认为其他sed人支持[\n])。它的工作原理是将每一行附加到H旧缓冲区,然后d如果不是最后一行则将其删除 ( $!)。在最后一行,它通过模式空间复制保留空间内容g(模式空间的内容\n现在以 ewline 开头)。如果模式空间中没有行以非空白 ( ) 开头,
则它会删除每行 ( ) 上的第一个字符。每次成功替换后,它都会分支回 label 。如果模式空间中至少有一行以非空白开头,则它只会从模式空间 ( ) 中删除前导换行符,然后自动打印它。s/\n[^\n]/\n/g/\n[^\n[:blank:]]/!ms/.//

答案2

如果您只关心输出的第一行,则通过仅寻址第 1 行来限制 sed 查看的内容:

printf ' some text\n\n some more text\n' |sed '1s/^[ \t]*\([^ \t]\+.*\)$/\1/'

这将忽略开头的任何空白,然后匹配非空白的内容以及该行的其余部分,并且仅在第 1 行上进行匹配。

相关内容