删除文件的前 n 个字节

von*_*ann 34 sed awk text-processing files

我有一个极端的问题,我能想到的所有解决方案都很复杂。根据我的 UNIX/Linux 经验,一定有一个简单的方法。

我想删除/foo/. 每个文件都足够长。好吧,我相信有人会为我提供一个我无法想象的非常简单的解决方案。也许awk?

jll*_*gre 29

for file in /foo/*
do
  if [ -f "$file" ]
  then
    dd if="$file" of="$file.truncated" bs=31 skip=1 && mv "$file.truncated" "$file"
  fi
done
Run Code Online (Sandbox Code Playgroud)

或者更快,感谢 Gilles 的建议:

for file in /foo/*
    do
      if [ -f $file ]
      then
        tail +32c $file > $file.truncated && mv $file.truncated $file
      fi
    done
Run Code Online (Sandbox Code Playgroud)

注意:Posix tail 指定“-c +32”而不是“+32c”,但 Solaris 默认 tail 不喜欢它:

   $ /usr/bin/tail -c +32 /tmp/foo > /tmp/foo1
    tail: cannot open input
Run Code Online (Sandbox Code Playgroud)

/usr/xpg4/bin/tail 两种语法都很好。

如果要保留原始文件权限,请替换

... && mv "$file.truncated" "$file"
Run Code Online (Sandbox Code Playgroud)

经过

... && cat "$file.truncated" "$file" && rm "$file.truncated"
Run Code Online (Sandbox Code Playgroud)


ale*_*lex 14

以下命令从$file$file~用作临时副本)剪切前 31 个字节:

dd if="$file" of="$file~" bs=1 skip=31
mv "$file~" "$file"
Run Code Online (Sandbox Code Playgroud)

您只需要列出或find所有文件,/foo/并为每个$file找到的执行上述两个文件。

  • 交换 bs 和 skip 值会提高性能。 (2认同)

Gil*_*il' 11

tail -c +32输出其输入减去前 31 个字节。(是的,论点错了一个。)要就地编辑文件,请在循环中使用海绵,或者如果您没有它并且不想打扰,请在 shell 中执行它的工作:

for x in /foo/*; do tail -c +32 "$x" | sponge "$x"; done
for x in /foo/*; do tail -c +32 "$x" >"$x.new" && mv "$x.new" "$x"; done
Run Code Online (Sandbox Code Playgroud)

如果命令因任何原因(例如电源故障)而中断,则可能很难弄清楚您是从哪里中断的。将新文件写入单独的目录会使事情变得更容易。

mkdir /foo.tmp
cd /foo
for x in *; do tail -c +42 -- "$x" >"/foo.tmp/$x" && rm -- "$x"; done
mv /foo.tmp/* /foo
rmdir /foo.tmp
Run Code Online (Sandbox Code Playgroud)

如果文件真的很大(例如,大到足以有两个副本,即使是一个副本也是一个问题),您可以使用此线程中提到的技术之一