
次のリストがあります。
$$<002L_tbfl
Putative transcription factor 001R;
GO:0006355
GO:0046782
GO:0006351
IPR007031
$$<002L_FRG3G
Uncharacterized protein 002L;
GO:0033644
GO:0016021
IPR004251
私はそれぞれが新しい行を開始して再び表示される$$<
まで、同じ行(タブで区切られた)に次の項目を持たせたいと思います。$$<
このように:
$$<002L_tbfl Putative transcription factor 001R; GO:0006355 GO:0046782 GO:0006351 IPR007031
$$<002L_FRG3G Uncharacterized protein 002L; GO:0033644 GO:0016021 IPR004251
これまでの私のアプローチは次のとおりです。
tr '\n' '\t' < stage1 > stage2
sed 's/$$</\n/g' stage2 > stage3
問題は、上記の方法が小さなファイルでは完全に機能しますが、4 GBファイルでは機能しているように見える次の短い時間にエラーやメッセージなしで空のファイルを返すことです。
私も試してみましたが、tr '$$<' '\n'
うまくいきません。奇妙なファイルが生成されます。
答え1
実行方法は次のとおりですsed
。
sed -n '/$$</! H; /$$</{x; s/\n/\t/gp}; ${x; s/\n/\t/gp}' stage1 > stage3
部分に分かれています:
sed -n
デフォルト出力(つまり、処理された入力)が印刷されず、p
コマンドを受け取った場合にのみ印刷されることを意味します。/$$</! H
線が見える時を意味します。いいえ含まれている場合は$$<
「に追加してください。時間前のスペース"(たとえば、準備領域)。これは、一般的なロジックを反転して、"この条件を満たさない行に対してこれを実行することを!
意味します。$$<
(および(たとえば、行の前に改行を挿入するなどの行の途中を別々に処理する必要がある/^$$</
場合は、それを記録するように質問を編集してください。)$$<
予約済みスペース(予約済みスペース)に既にコンテンツがある場合予約済みスペースに行を追加する場合、その間
sed
に改行文字を挿入すると、予約済みスペースに次のテキストが作成されます。$$<002L_tbflnewline推定転写因子001Rnewline移動:0006355…
スペースを「パターンスペース」(通常の作業行バッファー)として予約 一般的に言えば最後に明示的な改行文字はありません(暗黙的です)。もちろん、スペース内に明示的に改行文字を挿入できます。
/$$</{…}
中かっこで囲まれたコマンドを含む行で実行されることを示します$$<
。x
eを意味するX予約済みスペースとパターンスペースの内容を変更します。s/\n/\t/gp
意味 - まあ、当然のことです、そうですか? - これは(パターンスペースで)改行文字をタブに置き換えることを意味します。 G世界中で血結果を印刷します。
このコマンドが入力の最初の行(を含む
$$<
)を読み取ると、x
その行($$<002L_tbfl
)をパターンスペースから予約済みスペースに移動し、予約済みスペースの前の内容をパターンスペースに移動します。ただし、予約済みスペースの最初の内容は何もないため、コマンドは適用されませんs
。後で(たとえば、7行目で)表示すると$$<
(上記のように)、新しい行を含むテキストをパターンスペースにインポートし(上記のように)、すべての改行をタブに置き換えて結果を印刷します。${…}
入力の終わりに達すると、中かっこで囲まれたコマンドが実行されることを示します。これは$$<
、予約済みスペースで最後の行(つまり、最後の行)をクリアするためにを表示したときに実行したのと同じコマンドです。
警告:POSIXでの動作は保証されませんsed
。私はそれをGNUでテストしましたsed
。
答え2
$ cat ip.txt
$$<002L_tbfl
Putative transcription factor 001R;
GO:0006355
GO:0046782
GO:0006351
IPR007031
$$<002L_FRG3G
Uncharacterized protein 002L;
GO:0033644
GO:0016021
IPR004251
$ perl -ne 'chomp if !eof; if($. > 1){print /\$\$</ ? "\n" : "\t"} print' ip.txt
$$<002L_tbfl Putative transcription factor 001R; GO:0006355 GO:0046782 GO:0006351 IPR007031
$$<002L_FRG3G Uncharacterized protein 002L; GO:0033644 GO:0016021 IPR004251
chomp if !eof
ファイルの最後の行を除くすべての入力行から改行を削除します。if($. > 1)
1より大きい行番号を入力してください。print /\$\$</ ? "\n" : "\t"
行が一致する場合は改行を追加し$$<
、そうでない場合はタップします。print
入力ライン印刷
答え3
おそらく32ビット制限があり、ストリーミングのみ可能です。次のようawk
なものを使用できます
awk 'NR==1 {printf "%s",$0; next;} $1~/^\$\$</ {printf "\n%s",$0; next;} {printf "\t%s",$0;}' < file
$$<
これにより、最初の行で始まる行(最初の行以降)を除いて、改行なしですべての入力行が連続して印刷されます。
たぶん、ENDセクションが必要な最後の改行文字が欲しいかもしれません。これらの変更を確認してくださいman awk
。
答え4
Ubuntu 12では、MawkとGawk 3.xで動作し、正規表現をサポートしていRS
ます。
$ awk 'BEGIN { RS="\\$\\$<"; FS="\n"; OFS="\t" } NF && $1="$$<"$1' data
出力:
$$<002L_tbfl Putative transcription factor 001R; GO:0006355 GO:0046782 GO:0006351 IPR007031
$$<002L_FRG3G Uncharacterized protein 002L; GO:0033644 GO:0016021 IPR004251
単に$$<
改行文字をレコード区切り文字として使用し、改行文字をフィールド区切り文字として使用します。
これは次のことを意味します。
- 入力はレコード区切り文字で始まるので、空のレコードを取得します。次の条件を使用してこの問題を解決します
NF
。フィールド数はゼロでなければなりません。 $$<
入力から削除されました。私たちはそれを入れました$1
。
中央にタブ付きのフィールドを印刷するには、タブを出力フィールド区切り記号(OFS
)に設定します。 { print }
モードのデフォルト動作なので無視します。
我々が修正したという事実は、すべてのフィールド結合を使用してレコード変数を更新する$1
副作用もあります。この更新がない場合、元のレコードは改行などを含むそのまま印刷されます。$0
OFS