ややメモリ効率の良い方法で文字列を「バイナリ」検索/置換する非ラインベースのツールを知っている人はいますか?this質問 も。
これが行うように見えるものと同様に処理したい+ 2GBのテキストファイルがあります。
sed -e 's/>\n/>/g'
つまり、>
の後にある改行をすべて削除し、他の場所は削除しないようにして、tr -d
を除外します。
このコマンド(-- 同様の質問の答え から取得)はcouldn't re-allocate memory
で失敗します。
sed --unbuffered ':a;N;$!ba;s/>\n/>/g'
では、Cに頼らずに他の方法はありますか?私はPerlが嫌いですが、この場合は例外としても構わないでしょう:-)
データに含まれていない文字が確実にわからないので、\n
を一時的に別の文字に置き換えることは、できれば避けたいものです。
いいアイデアはありますか?
これはPerlでは本当に簡単です。嫌いにしないでください!
Perl -i.bak -pe 's/>\n/>/' file
-i
:ファイルを編集して、元のfile.bak
のバックアップを作成します。バックアップが必要ない場合は、代わりにPerl -i -pe
を使用してください。-pe
:入力ファイルを1行ずつ読み取り、-e
として指定されたスクリプトを適用した後、各行を出力します。s/>\n/>/
:sed
と同様の置換。そして、これがawk
アプローチです:
awk '{if(/>$/){printf "%s",$0}else{print}}' file2
Perl
ソリューション:
$ Perl -pe 's/(?<=>)\n//'
説明
s///
は文字列置換に使用されます。(?<=>)
は後読みパターンです。\n
は改行に一致します。パターン全体は、その前に>
があるすべての改行を削除することを意味します。
これはどう:
sed ':loop
/>$/ { N
s/\n//
b loop
}' file
GNU sedの場合は、-u
(--unbuffered
)質問ごとのオプション。 GNU sedもシンプルなワンライナーとしてこれに満足しています:
sed ':loop />$/ { N; s/\n//; b loop }' file
sed
は、最後の改行なしで出力を発行する方法を提供しません。 N
を使用するアプローチは基本的には機能しますが、不完全な行をメモリに格納するため、行が長くなりすぎると失敗する可能性があります(sedインプリメンテーションは通常、極端に長い行を処理するように設計されていません)。
代わりにawkを使用できます。
awk '{if (/<$/) printf "%s", $0; else print}'
別の方法は、tr
を使用して、改行文字を「退屈な」頻繁に発生する文字と交換することです。ここでスペースが機能する可能性があります。データのすべての行または少なくとも行の大部分に表示される傾向のある文字を選択してください。
tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'
edの使用についてはどうですか?
ed -s test.txt <<< $'/fruits/s/Apple/banana/g\nw'
sed
をN
コマンドで使用できるはずですが、トリックは、パターンスペースから1行を削除するたびに削除することです(そのため、パターンスペースには常にファイル全体を読み取ろうとするのではなく、2つの連続した行)-試します
sed ':a;$!N;s/>\n/>/;P;D;ba'
編集:再読後 Peteris Krumins 'Famous Sed One-Liners Explained Iより良いsed
ソリューションが
sed -e :a -e '/>$/N; s/\n//; ta'
これは、最後に>
がすでに一致している場合にのみ次の行を追加し、条件付きでループ処理して連続する一致する行の場合(それはKruminの39です。次の行の置換を除いて、バックスラッシュ「\」で終了する場合は、行を次の行に追加します>
for \
for the join character、and the fact that the join character istained in the output)).