ディレクトリからすべてのファイルの最後の行を削除する方法は?

ディレクトリからすべてのファイルの最後の行を削除する方法は?

ディレクトリに多くのテキストファイルがあり、ディレクトリ内の各ファイルの最後の行を削除したいと思います。

どうすればいいですか?

答え1

GNUがあれば、この素晴らしいオネライナーを使うことができますsed

 sed -i '$ d' ./*

現在のディレクトリに隠されていないすべてのファイルの最後の行を削除します。-iGNUのスイッチはsedその場で動作することを意味し、'$ d'コマンドはsed最後の行を削除します($最後の行を意味、d削除を意味します)。

答え2

他の答えは、ディレクトリに通常のファイル以外の内容、またはファイル名にスペース/改行があるファイルが含まれている場合に問題があります。とにかく動作する方法は次のとおりです。

find "$dir" -type f -exec sed -i '$d' '{}' '+'
  • find "$dir" -type f: ディレクトリ内のファイルの検索$dir
    • -type f一般文書とは何ですか?
    • -exec見つかった各ファイルに対してコマンドを実行します。
    • sed -i:ファイルを所定の位置に編集します。
    • '$d'd最後()$行を削除()します。
    • '+':find に引数を追加し続けるように指示しますsed(各ファイルに対して個別にコマンドを実行するよりも効率的です.@zwol に感謝します).

-maxdepth 1サブディレクトリに移動したくない場合はfind

答え3

GNUを使用することは、sed -i '$d'ファイル全体を読み込み、最後の行なしでコピーを作成することを意味しますが、ファイルを直接切り取る方が効率的です(少なくとも大きなファイルの場合)。

GNUを使用すると、truncate次のことができます。

for file in ./*; do
  [ -f "$file" ] &&
    length=$(tail -n 1 "$file" | wc -c) &&
    [ "$length" -gt 0 ] &&
    truncate -s "-$length" "$file"
done

ファイルが比較的小さい場合、ファイルごとに複数のコマンドを実行するため、効率が低下する可能性があります。

最後の改行(最後の行の後ろ)の後に余分なバイトを含むファイルの場合、つまり区切りのない最後の文字がある場合ワイヤーtail、実装に応じて、tail -n 1GNUなどの追加バイトのみを返すtailか、最後の(正しく区切られた)行と追加バイトのみを返します。

答え4

より携帯性に優れた方法:

for f in ./*
do
test -f "$f" && ed -s "$f" <<\IN
d
w
q
IN
done

私はこれが説明を必要としないと思います...この場合を除いて、おそらく基本的に最後の行を選択するのと同じですd。これは再帰的に検索されず、隠しファイル(別名ドットファイル)も処理しません。この項目も編集するには、次を参照してください。$ded

*をディレクトリ内の隠しファイルと一致させる方法

関連情報