以下を使用して末尾のスペースを削除しています。
sed -i 's/[ \t]*$//' *.txt
ただし、このコマンドはすべてのファイルを書き換えます。
テキストファイルの後ろにスペースがあることを確認し、そうでないスペースをスキップする便利な方法はありますか?
答え1
変更する必要がある行があるかどうかを確認するには、firstを使用できます。grep
ただし、最悪の場合(最後の行だけを修正する必要がある場合)は、ファイルを2回読み続けます。
for f in ./*.txt; do
grep -q '[[:blank:]]$' "$f" &&
sed -i 's/[[:blank:]]*$//' "$f"
done
答え2
1つのアプローチは次のとおりですfind/grep/sed
。
find . -maxdepth 1 -type f -name '*.txt' \
-exec grep -q '[[:blank:]]$' {} \; \
-exec sed -Ei -e 's/[[:blank:]]+$//' {} +
- 現在のディレクトリで 1 を実行すると、-maxlength が検索に使用されます。
{} \;
はに渡されるファイルの名前を表し、コマンドの終了grep
者\;
であるシェルメタ文字セミコロンをエスケープします。私たちはそれが到着できるようにそれから走ります-exec
。次のように書くこともできます。';'
{} +
{}
これまで知っているように、これはできるだけ多くの+
ファイル名を渡すことを意味します(デフォルトでは、現在の結果に対して単一のファイル名をsed
渡すのではなく、呼び出し前に引数として使用するリストを蓄積します)。これにより、通話回数を最小限に抑えることができます。{}
find
{}
sed
sed
答え3
編集を実行して、違いがある場合にのみ元のファイルを置き換えます。
for file in *.txt
do
sed 's/[ \t]*$//' < "$file" > "$file.tmp.$$" || continue
cmp -s -- "$file" "$file.tmp.$$" ||
cat < "$file.tmp.$$" > "$file" ||
continue
rm -f -- "$file.tmp.$$"
done
答え4
次の内容は、次の内容に基づいています。エマ・ルーオの考えすべてのファイルに対して式を実行しますsed
が、実際に変更されたファイルのみを保持します。
呼び出しを減らしてsed
それを修正します。
printf '%s\0' ./*.txt |
xargs -0 sed -i.bak 's/[[:blank:]]$//
*.txt
その後、ファイルを参照し、ソースと比較し、アーカイブしたいファイルを選択できます。
for name in ./*.txt; do
if cmp -s "$name" "$name.bak"; then
# keep original
mv "$name.bak" "$name"
else
# keep modified
rm "$name.bak"
fi
done
または、両方を同時に実行します。
printf '%s\0' ./*.txt |
xargs -0 sh -c '
sed -i.bak "s/[[:blank:]]$//" "$@"
for name do
if cmp -s "$name" "$name.bak"; then
mv "$name.bak" "$name"
else
rm "$name.bak"
fi
done' sh