最初の行に基づいて12000個のファイルを4つのファイルにリンクする方法は?

最初の行に基づいて12000個のファイルを4つのファイルにリンクする方法は?

私のフォルダに12,000個のファイルがあり、大きなファイルにcsplitを使用しているため、同様の命名規則があります。ファイルの最初の行に基づいてこれらのファイルを並べ替えてから、同様のファイルをリンクする必要があります。

各ファイルの最初の行は「> 1」、「> 2」、「> 3」、または「> 4」で始まるため、最終的にすべての「> 4」ファイルは1つの凝集ファイルで終わる必要があります。この> 4ヘッダーを削除する必要はありません)

例:

ファイルxx1 xx3000とxx449は次のとおりです。

> 4 speciesX1
ATGC

私はそれを次のように見せるべきです。

> 4 speciesX1
ATGC
> 4 speciesX3000
ATGC
> 4 speciesX449
ATGC

sed -n -e '/> 4/,/>/ p' big_file >speciesX.txt を使用して元のファイルを分割しようとしましたが、目的のチャンクが印刷されなかったので、誰でも私を助けることができますか?

ベストアンサー1

awk 'FNR==1 && ! /^> 4/ {nextfile}1' * > speciesX.txt

現在のファイルが最初の行で始まらない場合は、次のファイルに移動します> 4。他のすべての行は標準出力として印刷されます。 stdoutはspeciesX.txtシェルによってリダイレクトされます。

注:1スクリプトの最後にtrueと評価、awkの基本操作を実行します(現在の行印刷)。awkawkスクリプトは基本的にtest-condition { action-if-true }テスト条件や操作を省略できる一連のルールなので、これは一般的な慣用語です。テスト条件がない場合は常に対応するアクションが実行され、アクションがない場合はprintデフォルト値が使用されます。


上記の行を一致などに合わせて変更して実行するたびに別のファイルにリダイレクトするのは簡単ですが、すべての/^> 1/入力/^> 2/ファイルの出力ファイルを一度に作成し、スクリプトを一度だけ実行するには、次のようにします。物事:

awk 'FILENAME ~ /\.out$/ {nextfile};
     FNR==1 && ! /^> [0-9]/ {nextfile};
     FNR==1 {outfile=$2 ".out"};
     {print > outfile}' *.txt

まず、現在の入力ファイルがで終わっていることを確認してください.out。その場合は、次のファイルにジャンプします。すべての入力ファイルがたとえば終わる場合は必要ありませんが、.txtそれが本当かどうかはわかりません(言わなかった)、そのケースを適切に処理する方が良いでしょう。

>次に、各ファイルの最初の行を確認し、許容可能なパターン(たとえば、「で始まり、スペース、数字が続きます」)と一致しない場合は、次のファイルに移動します。

それ以外の場合は、出力ファイル名を設定するために、最初の行の2番目のフィールドに「.out」が追加されます。

これにより、入力の各行が出力ファイル名で印刷されます。ファイル、、、1.outなどで終わります。後で を使用して名前を変更できます。2.out3.out4.outmv

awkでのリダイレクトはシェルとは少し異なり>ます。>>

  • シェルは既存のファイルを削除して上書きします。>使用するたびに(ファイルに追加を使用する必要があります>>)。
  • awkはファイルを削除して上書きします。ただ最初ファイル名が表示されます単一スクリプト実行内で、後続のすべての出力は同じファイル名に追加されます(同じスクリプト実行内)。 >>これにより、スクリプトが最初にファイル名を解決した場合でも、削除と上書きを防ぎます。つまり、常に追加されます。

ちなみに、スクリプトの最後の行は{print > outfile}テスト条件なしでアクションを実行するawkルールの例です。これは各入力行に対して行われます(前の規則が次の行またはファイルと同様に機能するnextか、すぐにジャンプしない限り)。nextfile

おすすめ記事