2

我正在尝试通过删除重复的空行来压缩文本文档,使用sed. 这就是我正在做的(无济于事):

sed -i -E 's/\n{3,}/\n/g' file.txt

根据本手册,我知道这是不正确的,但我不知道如何正确地做到这一点。谢谢。

4

6 回答 6

4

我认为您想用单个空行替换多个空行的跨度,即使您的示例用\n单个\n而不是\n\n. 考虑到这一点,这里有两个解决方案:

sed '/^$/{ :l
    N; s/^\n$//; t l
    p; d; }' input 

在 sed 的许多实现中,这可以全部在一行上,嵌入的换行符被替换为;.

awk 't || !/^$/; { t = !/^$/ }'
于 2012-09-11T19:50:19.943 回答
4

正如上面所建议的 Tripleee,我使用 Perl 而不是sed

perl -0777pi -e 's/\n{3,}/\n\n/g'
于 2012-09-25T09:06:45.000 回答
3

使用翻译功能

 tr -s '\n'

-s 或 --squeeze-repeats 将重复字符序列减少为单个实例。

于 2012-09-11T15:41:10.560 回答
1

tr -s '\n'or处理得更好cat -s,但如果您坚持使用sed,这里有一个来自 GNU sed 手册第 4.17 节的示例:

#!/usr/bin/sed -f

# on empty lines, join with next
# Note there is a star in the regexp
:x
/^\n*$/ {
  N
  bx
}
# now, squeeze all '\n', this can be also done by:
# s/^\(\n\)*/\1/
s/\n*/\
/
于 2012-09-11T20:47:12.303 回答
0

我不确定这是 OP 想要的,但如果您想删除文件中的所有空行,则使用 William Pursell 的 awk 解决方案是一种方法:

awk '!/^$/' file.txt

解释:

awk 模式

'!/^$/'

正在测试当前行是否仅由行首(用'^'表示)和行尾(用'$'表示)组成,换句话说,该行是否为空。

如果此模式为真,则 awk 应用其默认值并打印当前行。

高温高压

于 2019-06-25T19:15:22.883 回答
0

我认为 OP 想要压缩空行,例如,如果有 9 个连续的空行,他想要只有三个。我已经编写了一个小 bash 脚本来做到这一点:

#! /bin/bash
TOTALLINES="$(cat file.txt|wc -l)"
CURRENTLINE=1
while [ $CURRENTLINE -le $TOTALLINES ]
do
    L1=$CURRENTLINE
    L2=$(($L1 + 1))
    L3=$(($L1 +2))
    if [[ $(cat file.txt|head -$L1|tail +$L1) == "" ]]||[[ $(cat file.txt|head -$L1|tail +$L1) == " " ]]
    then
        L1EMPTY=true
    else 
        L1EMPTY=false
    fi
    if [[ $(cat file.txt|head -$L2|tail +$L2) == "" ]]||[[ $(cat file.txt|head -$L2|tail +$L2) == " " ]]
    then
        L2EMPTY=true
    else 
        L2EMPTY=false       
    fi
    if [[ $(cat file.txt|head -$L3|tail +$L3) == "" ]]||[[ $(cat file.txt|head -$L3|tail +$L3) == " " ]]
    then
        L3EMPTY=true
    else 
        L3EMPTY=false       
    fi  
    if [    $L1EMPTY = true ]&&[    $L2EMPTY = true ]&&[    $L3EMPTY = true ]
    then
        #do not cat line to temp file
        echo "Skipping line "$CURRENTLINE   
    else
        echo "$(cat file.txt|head -$CURRENTLINE|tail +$CURRENTLINE)">>temp.txt
        echo "Writing line " $CURRENTLINE
    fi
    ((CURRENTLINE++))
done    
cat temp.txt>file.txt
rm -r temp.txt
FINALTOTALLINES="$(cat file.txt|wc -l)"
EMPTYLINELINT=$(( $CURRENTLINE - $FINALTOTALLINES ))
echo "Deleted " $EMPTYLINELINT " empty lines."

于 2022-02-19T08:17:35.787 回答