回答:
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
または高速、Gillesの提案のおかげで:
for file in /foo/*
do
if [ -f $file ]
then
tail +32c $file > $file.truncated && mv $file.truncated $file
fi
done
注:Posixの末尾は、「+ 32c」ではなく「-c +32」を指定しますが、Solarisのデフォルトの末尾はこれを好みません。
$ /usr/bin/tail -c +32 /tmp/foo > /tmp/foo1
tail: cannot open input
/usr/xpg4/bin/tail
両方の構文で問題ありません。
dd
ここで提案するのは過剰でtail
あり、より適切です(より単純で、キラータイプミスのリスクが少なく、stderrに偽のメッセージがありません)。
cut
(それは尻尾ではないだろうか?...そのまま、それは私にはうまくいかない
/usr/xpg4/bin
先の/usr/bin
あなたにPATH
、またはあなたが1990年代初頭に立ち往生することがあります。多くのユニックス(GNU、BusyBoxなど)は、歴史的な+32c
構文をサポートしなくなりました+32c
(POSIXが要求するように)と呼ばれるファイルを意味します。
tail -c +32
入力から最初の31バイトを引いた値を出力します。(はい、引数は1つずれています。)ファイルを所定の場所で編集するには、スポンジをループで使用します。または、ファイルがなくて気にしたくない場合は、シェルでその作業を行います。
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
何らかの理由(停電など)でコマンドが中断された場合、中断した場所を特定するのは困難です。新しいファイルを別のディレクトリに書き込むと、作業が簡単になります。
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
ファイルが非常に大きい場合(たとえば、1つでも2つのコピーが存在することが問題になるほど大きい場合)、このスレッドで説明されている手法のいずれかを使用できます。