ファイルの最後のテキスト行を見つけて、最後のカンマを削除したいと思います。私この質問はすでにリクエストされています。しかし、答えを受けた後、私の質問は十分に具体的ではないことに気づきました。
この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
置換セクションで「このサブパターンが一致するもの」を意味するために使用できます。\Z
Perl 専用の拡張子で、使用される文字列の末尾と一致します。この場合はファイル全体です。- 置換部分では、
\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