从多个文件中删除前 10 行

从多个文件中删除前 10 行

文件file00通过file99(百个文件)命名。它们都在同一个目录中。如何抓取所有一百个文件并删除每个文件的前 10 行?我使用的是 CentOS 7。

答案1

file00这将从名称范围为到 的所有文件中删除前十行file99

sed -i.bak -n '11,$p' file[0-9][0-9]

这可能需要 GNU ,这在 OSX 上sed被称为。gsed对于其他 sed,请尝试:

find file[0-9][0-9] -maxdepth 0 -type f -exec sed -i.bak -n '11,$p' {} \;

怎么运行的:

  1. -i.bak告诉 sed 就地修改文件,创建扩展名为 .bak 的备份文件

  2. -n告诉 sed 不要打印任何行,除非我们明确要求它打印。

  3. 11,$p告诉 sed 打印从第 11 行开始到$文件中最后一行(表示为 )的行。

  4. file[0-9][0-9]是一个 shell glob,它将扩展以匹配名称由file后跟两位数字组成的所有文件。

选择

逻辑可以颠倒。我们可以(提示:JigglyNaga)删除前十行,而不是显式打印第 11 行及之后的行:

sed -i.bak '1,10d' file[0-9][0-9]

答案2

bash在(或任何类似 Bourne 的 shell)和 GNU 或 BSD中使用简单循环sed

for f in file[0-9][0-9]; do
  sed -i '.bak' '1,10d' "$f"
done

编辑sed脚本1,10d将从输入流中删除第 1 行到第 10 行。其他行将被输出。我们-i '.bak'要求sed在文件中进行内联编辑,但要使用后缀备份原始文件.bak

具有显式循环的替代方案(允许子间隔、ksh93bash语法zsh):

for (( i = 0; i < 100; ++i )); do
  f="$( printf "file%02d" "$i" )"
  sed -i '.bak' '1,10d' "$f"
done

使用ksh93or zsh,另一种方式:

typeset -Z 2 j
for (( i = 0; i < 100; ++i )); do
  j=$i
  sed -i '.bak' '1,10d' "file$j"
done

typeset -Z 2 j强制$j转换为宽度为 2 的零填充数字。我们不希望typeset i以这种方式,因为一旦达到 100,它的值就会变成00100,从而有效地将循环变成无限循环。这是 for ksh93zsh似乎能够处理它,因为它显然在将其提交到格式化之前使用了该值。

答案3

为了避免创建临时文件或影响文件的权限、所有权或其他属性,请使用ksh93

for f in file{2}([0-9]); do
  tail -n +11 < "$f" 1<>; "$f"
done

重定向<>;操作符的作用类似于<>(以读+写模式打开),不同之处在于 shell 在命令成功退出时在命令离开的位置截断文件。

所以,我们基本上是在覆盖文件本身。

答案4

如果您更喜欢 bash 循环:

for f in file[0-9][0-9]; do
    tail -n +11 "$f" > tmp &&
    mv -f tmp "$f"
done

相关内容