空でない最後の行のテキストを置き換える方法は?

空でない最後の行のテキストを置き換える方法は?

ファイルの最後のテキスト行を見つけて、最後のカンマを削除したいと思います。私この質問はすでにリクエストされています。しかし、答えを受けた後、私の質問は十分に具体的ではないことに気づきました。

このsedコマンドはファイルの最後の行に移動して操作を実行します。私の場合は、末尾のカンマを削除したいと思います。

sed -i '$ s/",/"/g' file.txt

だからこれ:

blah blah blah,
blah blah blah,
blah blah blah,

...次のようになります。

blah blah blah,
blah blah blah,
blah blah blah

しかし、テキストの最後の行の後に空白行がある場合は機能しません。ファイルから。

私はテキストの最後の行を取得する方法を探していましたが、私が理解して適用できるものが見つかりませんでした。また、すべての末尾の空白行を削除する方法を見つけ、次のコマンドを見つけました。

sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' *.txt

しかし、それは私にとってはうまくいきません(コマンドラインに私のファイルの内容を出力するようです)。とにかくこれはエレガントではありません。次の空行を削除したくありません。テキストを含む最後の行を識別し、それに応じてアクションを実行する方が良いでしょう。

最後の行からカンマを削除する方法テキスト1つのディレクトリに複数のファイルがありますか?

答え1

大容量ファイルの場合は、より速いGuruの回答を使用してください。しかし、小さなファイル(25行未満)では、これが少し速いことがわかりました(GNU tacがあると仮定)。

tac file | awk '!/^[[:blank:]]*$/{i++;if(i==1){sub(",$","")}}1' | tac

答え2

回答

perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt

.txt最後の ',' は ',' の後にゼロ個以上の改行だけがあり、ファイルの終わりが来ると ',' で終わるすべてのファイルから削除されます。

あなたの例では:

reedm@www:~/tmp $ cat > test.txt
blah blah blah,
blah blah blah,
blah blah blah,


reedm@www:~/tmp $ perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt
reedm@www:~/tmp $ cat test.txt
blah blah blah,
blah blah blah,
blah blah blah


reedm@www:~/tmp $ 

ワット?

Perlは最高の瞬間に難解な獣であり、Perlの冗談は特に秘密である可能性があります。

この-eフラグを使用すると、コマンドラインからPerlプログラムを渡すことができます。この場合、「s/regex/replace/flags」はプログラムです。

このフラグは、Perlが提供された各ファイル名の各「行」-pにループとして提供されたプログラムを適用するようにします(参考文献を参照)。-0

この-iフラグは、Perlが出力を標準出力に印刷するのではなく、ファイルをプログラムの出力に置き換えるようにします。

この-0フラグは、ファイルを「行」で区切るためにPerlが使用する区切り文字を変更します。0777慣例に従って使用すると、Perlがファイル全体を単一の「行」として読み取るようにする特別な値です。

正規表現は、いくつかのPerl関連のトリックのために少し複雑です。

  • まず、m末尾のフラグがあるため、正規表現は複数行で実行されます。
  • ,シンプルで、単一のカンマと一致します。
  • (\n*)1行にゼロ個以上の改行文字を一致させ、それをサブパターン((および)サブパターンを表す文字)として保存します。これは最初のサブパターンなので、\1置換セクションで「このサブパターンが一致するもの」を意味するために使用できます。
  • \ZPerl 専用の拡張子で、使用される文字列の末尾と一致します。この場合はファイル全体です。
  • 置換部分では、\1一致を一連の改行文字で置き換え、カンマを削除します。

Perl正規表現とPerlコマンドラインフラグの詳細については、およびperlre各マニュアルページを参照してくださいperlrun

答え3

Perlソリューションがあなたに適している場合:

 perl -00pe 's/(.*),/$1/s' file

ファイル自体の変更を保存するには:

perl -i -00pe 's/(.*),/$1/s' file

複数のファイルに適用するには:

perl -i -00pe 's/(.*),/$1/s' *.txt

答え4

sedファイル全体の内容を「パターンスペース」で1行として処理できるように、複数行の検索モードと置換モードに入ります。

(注:FreeBSDでは、正しい内部ファイルを編集するためにsedオプションの順序が必要です。)-n -i -e

# delete the last , in the last non-empty line of a file
# cf. http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/

cat -n testfile

sed -n -i -e '
# if the first line copy the pattern to the hold buffer
1h
# if not the first line then append the pattern to the hold buffer
1!H
# if the last line then ...
$ {
# copy from the hold to the pattern buffer
g
# remove last , in last non-empty line of file 
#s/,\([^,[:cntrl:]]*\n*\)$/\1/
s/,\([^,]*\)$/\1/
p
}' testfile

関連情報