如何在Linux中替换多个文件最后n行的字符串

如何在Linux中替换多个文件最后n行的字符串

我怎样才能替换多个文件的‘最后 10 行’中的字符串?

我有大约 100 个具有相同扩展名“.txt”的文件,我想将每个文件最后 10 行中的字符串“GLN”替换为“LOO”。我该怎么做?我知道如何对一个文件执行此操作,但不知道如何对多个文件执行此操作。当我使用此命令时;

for i in `head -3 *.txt  | awk '{print $4}'`
     do
                   sed -i 's/GLN/LOO/g' *.txt 
     done

它会替换文件中出现的所有 GLN,而不仅仅是最后 10 行。请问我做错了什么?

答案1

head -3 *.txt | awk '{print $4}'由于您没有向我们展示您的文件样本,因此不清楚这里返回的内容,但sed -i 's/GLN/LOO/g' *.txt会替换所有的GLN 的实例全部中的线条全部匹配的文件*.txt,只要循环执行至少一次。

据我所知,没有直接的方法来解决最后一个问题nsed 中文件的行 - 因此要使用它,您需要从外部计算偏移量,使用wc -lshell 算术例如:

for f in *.txt; do 
  start=$(( $(wc -l <"$f") - 9 ))
  sed "$start"',$s/GLN/LOO/g' "$f"
done

(我删除了,-i以便将输出发送到终端进行测试)。如果您打算使用 awk,则可以使用类似的方法awk 'END{print NR-9}' "$f"来代替获取起始偏移量。$(( $(wc -l <"$f") - 9 ))

或者,你可以使用tac反转文件并首先进行替换n行,然后是tac结果——尽管这使得就地替换变得复杂。

在这种情况下,我可能会使用edex支持数字地址偏移,例如使用终端输出进行测试:

for f in *.txt; do 
  printf '%s\n' '$-9,$s/GLN/LOO/g' ',p' | ed -s "$f"
done

一旦你对它做了正确的事情感到高兴,就,p改为wq将结果写入文件(相当于 sed 的-i)。

答案2

我将使用 tac 和 awk 函数完成这项工作,如下所示:

tac file1.txt | awk 'NR<11 {gsub("GLN","LOO")};{print}' | tac

相关内容