在 Shell 中删除具有特定模式的行之后的行

在 Shell 中删除具有特定模式的行之后的行

我正在尝试删除文件中特定模式之后的所有行。

我有很多文件,它们都具有相同的结构:

例子:

文件1

line 1
...
line x "here there is a specific pattern"
...
EOF

文件 n

line 1
...
line x "here there is a specific pattern"
...
EOF

我试图得到一个简单的解决方案,但由于我有很多文件,所以我走了很长的路:p

该模式在每个文件中出现一次。

因此,我获得了包含此模式的所有行号,并将其保存在一个文件中。

这是我的代码:

count=$(ls -f path_to_folder/*.txt | wc -l)
echo "Number of txt file : $count"
###


    for ((i=1;i < $count+1 ;i++))

    {

    vt=$(grep -n PATTERN $i.txt | cut -d : -f 1)
    echo $vt >> PATTERN_line.txt

    }

每个文件中的每一行都PATTERN_line.txt包含该模式所在的行号。

现在,我尝试使用这些数字来删除从模式到文件末尾的所有行。

这意味着我需要保留文件从头部到必须包含的模式行。

我感谢您的帮助

答案1

对于文本处理实用程序来说,这非常简单。例如,使用sed

sed '1,/pattern/!d' file

意思是,匹配从第一行到带有 的每一行pattern,并删除所有不匹配的行。因此,pattern用你的模式替换。如果它包含/,你需要转义这些字符。例如,如果模式是pattern-with/character

sed '1,/pattern-with\/character/!d' file

要实际编辑文件(而不是将编辑的流打印到标准输出),您可以使用以下标志-i

sed -i '1,/pattern/!d' file

您可以通过将旧文件的扩展名添加为 来备份原始文件-i。请注意 - 扩展名前不能包含空格。

sed -i.backup '1,/pattern/!d' file

sed接受多个文件名参数。例如,要对当前目录中的所有非隐藏文件执行操作,您可以使用:

sed -i '1,/pattern/!d' *

答案2

另一种解决方案是使用 awk:

awk '/specific-pattern/{stop=1} stop==0{print}' < input_file >> output_file

当变量stop为 0(默认情况下为 )时,awk 将打印当前行。但是,如果当前行与正则表达式/specific-pattern/,stop则会被设置为 1。这会导致stop==0不真实,因此 awk 将不再执行该print语句。

输入从输入文件读取并附加到输出文件。

如果要保留具有模式的行,请反转 awk 脚本的两个部分。

答案3

谢谢@Zanna

我找到了这个解决方案:

for ((i=1;i < $count+1 ;i++)) 

sed -n '/PATTERN/q;p' $i.txt > file_out$i.txt

谢谢

答案4

试试这个 shell 脚本。它接受 2 个参数作为输入。第一个参数是输入文件名。第二个参数是需要搜索的模式。它将在第一次匹配模式后删除行。

#!/bin/bash

touch temp.txt

while read line
do
    echo "$line" | grep "$2" &> /dev/null
    if [ $? -eq 0 ]
    then
        echo "$line" >> temp.txt
        mv temp.txt $1
        echo "STATUS: Pattern matched. Successful operation..."
        exit 0
    fi
    echo "$line" >> temp.txt
done < $1

echo "STATUS: Pattern not found. No lines are deleted..."
rm -f temp.txt

相关内容