awkはcat -Aを使用して示されているように.gzファイルに列を追加しますが、通常の出力で列名を変更します。

awkはcat -Aを使用して示されているように.gzファイルに列を追加しますが、通常の出力で列名を変更します。

を使用して、awkこのテーブルに最初の行が "INFO"で、残りの行が "1"の列を追加したいと思います。

$ gunzip -c foo.gz | head
SNPID   CHR BP  Allele1 Allele2 Freq1   Effect  StdErr  P.value TotalN
rs1000033   1   226580387   t   g   0.8266  -0.0574 0.0348  0.09867 17310
rs1000050   1   162736463   t   c   0.8545  0.0654  0.0461  0.1564  10864

どこ

gunzip -c foo.gz | head | cat -A
SNPID^ICHR^IBP^IAllele1^IAllele2^IFreq1^IEffect^IStdErr^IP.value^ITotalN^M$
rs1000033^I1^I226580387^It^Ig^I0.8266^I-0.0574^I0.0348^I0.09867^I17310^M$
rs1000050^I1^I162736463^It^Ic^I0.8545^I0.0654^I0.0461^I0.1564^I10864^M$

.gz私が使ったファイルです。

gunzip -c foo.gz | \
  awk 'BEGIN {FS="\t"; OFS="\t"} NR == 1 {print $0 OFS "INFO"} NR > 1 {print $0 OFS "1"}' | \
  gzip > foo.V2.gz

何らかの理由で、これは私の列名を変更するようですが、最後に予想される列は変更されません。

$ gunzip -c foo.V2.gz | head   
SNPID   INFO    BP  Allele1 Allele2 Freq1   Effect  StdErr  P.value TotalN
--------^
rs1000031   1   226580387   t   g   0.8266  -0.0574 0.0348  0.09867 17310
rs1000051   1   162736463   t   c   0.8545  0.0654  0.0461  0.1564  10864

奇妙なことは、cat -A柱を見れば元々なければならないところにあるようだということです。

$ gunzip -c foo.V2.gz | head | cat -A                                      
SNPID^ICHR^IBP^IAllele1^IAllele2^IFreq1^IEffect^IStdErr^IP.value^ITotalN^M^IINFO$
----------------------------------------------------------------------------^ 
rs1000033^I1^I226580387^It^Ig^I0.8266^I-0.0574^I0.0348^I0.09867^I17310^M^I1$
rs1000050^I1^I162736463^It^Ic^I0.8545^I0.0654^I0.0461^I0.1564^I10864^M^I1$

知りたい、

  1. ここで何が起こっているのでしょうか?
  2. gunzip -c foo.V2.gz | head今、その言葉を信じることができますかgunzip -c foo.V2.gz | head | cat -A
  3. 以下を使用して予想出力を取得する方法gunzip -c foo.V2.gz | head

SNPID   CHR BP  Allele1 Allele2 Freq1   Effect  StdErr  P.value TotalN INFO
rs1000033   1   226580387   t   g   0.8266  -0.0574 0.0348  0.09867 17310 1
rs1000050   1   162736463   t   c   0.8545  0.0654  0.0461  0.1564  10864 1

ノートSNPID=1; CHR=2; ...、私は私が指定した列番号が後続の分析に適しているかどうかに応じて現在の場所を定義するために設定スクリプトを使用しています。

答え1

すでに述べたように、DOS行の終わりがあります。バラより私のツール出力がそれ自体で上書きされる理由と回避策問題と考えられる回避策の説明(例:awkを使用):

gunzip -c foo.gz |
  awk -v OFS='\t' '{sub(/\r$/,""); print $0, (NR>1 ? 1 : "INFO")}' |
  gzip > foo.V2.gz

RS="\r\n"最近、1〜2つの異なるawkバリアントに採用されているGNU awk拡張であるマルチキャラRSを使用できます。他のPOSIX準拠のawk設定は、設定したRS="\r\n"ものと同じように扱われます。RS="\r"各POSIXはRS単一のリテラル文字しか使用できないためです。また、awkが表示する前にデフォルトのCプリミティブが行末を\r削除するシステムでは失敗するため、RS="\r?\n"より強力です。 awkの場合は、デフォルトRSのままにしてスクリプトの最初のステートメントとして\n追加できます。{sub(\r$/,"")}

また、不要な値または既に値を持つコード設定変数を削除し、2つの印刷ステートメントを1に変更し、OFSを設計どおりに使用し、パイプシンボルから不要なエスケープを削除するなど、スクリプトからいくつかの他のことも整理しました。その後行末。

答え2

入力した内容は、Microsoft 行末がある一種の TSV ファイルのようです。

その後利用できますmlr代わりに、awk2種類のtsvをサポートし、レコード区切り文字を指定できます。

  1. 値はabで区切られますが、、、、--tsv vを使用してフィールドにTAB、CR、およびLF文字を挿入できます。ts\\\t\r\n\
  2. 値はabで区切られ--tsvlite v、フィールド値に行区切り文字またはタブ文字を挿入することはできません。ts

ここでは、タイトルと値にこれらの文字がまったく含まれていない追加の列を追加したいので、それらのいずれかを使用しても影響はありません。

デフォルトでは、mlrCRLF(Microsoft)またはLF(Unix)行の区切り文字が許可され、LF(Unix)で区切られた行が出力されます。ただし、--rs crlfCRLF(Microsoft)で区切られた出力ラインに渡すことはできます。

だから:

< foo.gz gunzip |
  mlr --tsvlite put '$INFO = 1' |
  gzip > foo.V2.gz

出力時にUnix TSVをインポートし、入力時にMicrosoftまたはUnix TSVを許可します。

< foo.gz gunzip |
  mlr --tsvlite --rs crlf put '$INFO = 1' |
  gzip > foo.V2.gz

出力時にMicrosoft TSVをインポートし、入力時にMicrosoftまたはUnix TSVを許可します。

バージョン6.0.0以降、mlrgzip圧縮ファイル読み取り機能が組み込まれているため、次のこともできます。

mlr --tsvlite put '$INFO = 1' foo.gz |
  gzip > foo.V2.gz

--gzin(ファイルパスがで終わらない場合は、このオプションが渡されます.gz

mlr(ミラー、通常はmillerパッケージに出荷されます。)はテーブル形式のデータ処理に特化したツールです。これには一部が必要な場合があります。動詞sort、、cut...などのレコードに対してさまざまな操作を実行するためのjoinパラメータfilter

put以下を使用してレコードを変更するために使用されます。シンプルドメイン固有の言語状況はの場合と大きく変わりませんawk

awkたとえば、その言語では$レコードのフィールドを参照するために使用されます。このフィールドを除いて、名前付き1.の場合、$INFO = 1各レコードのフィールドにINFO数値²値を割り当てます1。フィールドがまだ存在しない場合は、そのフィールドが追加され、追加の列として表示されます。


1 ただし、次のように使用することもできます--implicit-csv-header

² $INFO = "1"JSONなどの出力形式に異なる影響を与える文字列に設定できますが、型の表示がないtsvの場合はそうではありません。

答え3

〜のように@スチールドライバ説明で述べたように、ファイルはWindowsでキャリッジリターン(CR)と改行(LF)文字で汚染されているように見え、同じ問題が再発生することRS="\r\n"なく設定されたレコード区切り文字を削除できます。ORS="\n"

gunzip -c foo.gz | \
  awk 'BEGIN {FS=OFS="\t";RS="\r\n";ORS="\n"} NR == 1 {print $0 OFS "INFO"} NR > 1 {print $0 OFS "1"}' | \
  gzip > foo.V2.gz

答え4

LF(Unix)またはCRの後にLF(Microsoft)があるかどうかにかかわらず、行区切り<tab>INFO文字の前に最初または後続の行を追加するには、次の手順を実行します。<tab>1

<foo.gz gunzip |
  perl -pe 's/(?=\r?$)/$. == 1 ? "\tINFO" : "\t1"/e' |
  gzip > foo.V2.gz

ファイルを内部で編集するには、理論的にはIOレイヤ-iでこのオプションを使用できる必要があります(別途インストールが必要な場合があります)。PerlIO::gzip

perl -Mopen=IO,gzip -i -pe 's/(?=\r?$)/$. == 1 ? "\tINFO" : "\t1"/e' foo.gz

私のバージョンが失敗したことを発見しましたが、foo.gzで内部編集を実行できません。一時名を生成できません。デバイスのioctlが不適切です。これは私にバグのように聞こえます。

関連情報