HOWTO · Bash
Bash で空行を削除する方法
このチュートリアルでは、Bash でテキストファイルの空行や空白だけの行を除外する方法を説明します。
このページの内容
テキストファイルに不要な空行が含まれている場合は、sed、grep、または awk を使って、ファイルを表示しながら空行を除外できます。以下の各コマンドは、残す行を標準出力に書き出すだけで、元のファイルは変更しません。これらは Bash のキーワードや組み込みコマンドではなく、Bash または別の POSIX 互換シェルから使うコマンドラインユーティリティです。
ストリーム編集のコマンドを使いたい場合は sed、一致する行を手短に除外したい場合は grep、フィルターをより大きなレコード処理スクリプトの一部にする場合は awk を選べます。結果を保存するには、コマンドの出力を別のファイルへリダイレクトし、元のファイルを置き換える前に内容を確認してください。これらのユーティリティは、Bash/Linux やその他の POSIX 互換のコマンドライン環境で一般的に利用できます。
Bash の入力ファイルを準備する
コマンドの例では、1_Test.txt に4行のテキストがあり、2行目と3行目の間に空行が1行あるとします。次の完全なスクリプトは、一時パスにファイルを作成してフィルターを適用し、結果を表示します。コマンドの終了後に一時ファイルを削除します。出力ブロックには、残った4行が表示されます。
temp_dir="$(mktemp -d)"
sample_file="$temp_dir/1_Test.txt"
printf '%s\n' \
'This is the first line.' \
'This is the second line.' \
'' \
'This is the third line.' \
'This is the fourth line.' > "$sample_file"
sed '/^[[:space:]]*$/d' "$sample_file"
rm -f "$sample_file"
rmdir "$temp_dir"
This is the first line.
This is the second line.
This is the third line.
This is the fourth line.
これにより、表示結果から空行が除外され、空行ではない4行は保持されます。
^[[:space:]]*$ という式は、空白だけで構成された行に対して、行の先頭から末尾まで一致します。そのため、文字がまったくない行だけでなく、スペースやタブだけを含む行にも同じコマンドを使用できます。
sed ユーティリティで行をフィルターする
sed は /^[[:space:]]*$/d を削除ルールとして扱います。パターンに一致した入力行は、d によって標準出力へ送るストリームから削除されます。サンプルファイルに対しては、sed '/^[[:space:]]*$/d' 1_Test.txt を実行します。
このコマンドは元のファイルを変更しません。新しいクリーンなファイルが必要な場合は、たとえば sed '/^[[:space:]]*$/d' 1_Test.txt > cleaned.txt のように出力を別のパスへリダイレクトし、元のファイルを置き換える前に確認してください。フィルター済みのストリームを保存するのはリダイレクトであり、sed 自体は元のパスを読み続けます。
grep ユーティリティで行をフィルターする
grep -v は一致を反転するため、^[[:space:]]*$ に一致しない行を表示します。1_Test.txt に対しては、grep -v '^[[:space:]]*$' 1_Test.txt を実行します。正規表現は sed コマンドと同じで、-v は grep に一致しない行を残すよう指示します。
sed の方法と同様に、grep は残した行を標準出力へ送り、入力パスの内容を編集しません。1つのパターンに一致する行を単純に除外したい場合に便利です。結果を保存する必要がある場合は、出力を別のファイルへリダイレクトしてください。
次の自己完結型の例では、grep フィルターを適用する前にサンプルファイルを作成するため、既存の補助ファイルに依存せずに利用できます。
temp_dir="$(mktemp -d)"
sample_file="$temp_dir/1_Test.txt"
printf '%s\n' \
'This is the first line.' \
'This is the second line.' \
'' \
'This is the third line.' \
'This is the fourth line.' > "$sample_file"
grep -v '^[[:space:]]*$' "$sample_file"
rm -f "$sample_file"
rmdir "$temp_dir"
awk ユーティリティで行をフィルターする
awk は、条件が真になるレコードを表示します。否定パターン ! /^[[:space:]]*$/ は、空白以外の文字を含むすべての行に対して真になります。そのため、awk '!/^[[:space:]]*$/' 1_Test.txt を実行すると、1_Test.txt の意味のある行が保持されます。
行のフィルターをより大きなレコード処理スクリプトの一部にする場合、この形式が役立ちます。他のコマンドと同様に、残したレコードだけを標準出力へ書き出し、1_Test.txt を置き換えることはありません。保存したコピーが必要な場合は、結果をリダイレクトするか、別のファイル編集手順を使用してください。
次の単独で実行できる例では、同じ形の入力を awk で処理し、後続のコマンドで使えるよう元のパスを残します。
temp_dir="$(mktemp -d)"
sample_file="$temp_dir/1_Test.txt"
printf '%s\n' \
'This is the first line.' \
'This is the second line.' \
'' \
'This is the third line.' \
'This is the fourth line.' > "$sample_file"
awk '!/^[[:space:]]*$/' "$sample_file"
rm -f "$sample_file"
rmdir "$temp_dir"