我正在尝试删除文件中特定模式之后的所有行。
我有很多文件,它们都具有相同的结构:
例子:
文件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