複数のファイルを解析して特定の行を抽出し、別のファイルに出力しようとしています。ただし、私のファイル内のこの情報の場所は、特定のパラメータによって変更されることがあります。
このために私は使用したいですif文。ほとんどの場合、抽出すべき内容は6行と7行にあります。
# IGBLASTN 2.5.1+
# Query: RL0575_B2_no210_RL0575_B2_ACPA_positive_LC
# Database: human_gl_V human_gl_D human_gl_J BCR_C_all.fa
# Domain classification requested: imgt
# V-(D)-J rearrangement summary for query sequence (Top V gene match, Top J gene match, Chain type, stop codon, V-J frame, Productive, Strand). Multiple equivalent top matches having the same score and percent identity, if present, are$
IGLV4-69*01 IGLJ1*01 VL No In-frame Yes +
このために私はこうします:
a=`ls *LC.fa | awk -F "." '{print $1}'`; #here i just strip the name of the files for the loop
for i in $a;
do cat $i.fmt7 | awk 'NR==6, NR==7' > $i.parsed.txt;
done
ただし、場合によっては6行目に追加の説明があるため、ファイルの8行目と9行目にこの情報が含まれます。
# IGBLASTN 2.5.1+
# Query: RL0624_B10_no15_RL0624_B10_ACPA_positive_LC
# Database: human_gl_V human_gl_D human_gl_J BCR_C_all.fa
# Domain classification requested: imgt
# Note that your query represents the minus strand of a V gene and has been converted to the plus strand. The sequence positions refer to the converted sequence.
# V-(D)-J rearrangement summary for query sequence (Top V gene match, Top J gene match, Chain type, stop codon, V-J frame, Productive, Strand). Multiple equivalent top matches having the same score and percent identity, if present, are$
IGKV3-20*01 IGKJ2*01 VK Yes In-frame No -
上記と同様の方法でやりたいのですが
a=`ls *LC.fa | awk -F "." '{print $1}'`; #here i just strip the name of the files for the loop
for i in $a;
if [my condition?] # <== here I do not know how to formulate the condition!
then
cat $i.fmt7 | awk 'NR==8, NR==9'
else
cat $i.fmt7 | awk 'NR==6, NR==7' > $i.parsed.txt;
fi
done
異なるプリアンブルの長さにもかかわらず、正しい行が抽出されるようにするにはどうすればよいですか?これらのファイルには、ここに示されているよりも多くのデータ行が含まれているため、最後の2行よりも多くの行を抽出する必要があります。
どんなアイデアにも感謝します。
答え1
ファイルに関連するデータ行が1つ含まれており、残りは空であるか、#
;で始まるコメント行があるようです。しかし、最後は維持したいヘッダーです。問題はコメントの行数が異なるようです。
ジョブが実際に「構文解析された」サマリーファイルに出力するためにヘッダーとこのデータラインを抽出する場合は、次のように、開始パターンで識別されたヘッダー以外の文字awk
で始まるすべての空行または行を無視するように指示できます。 。#
# V-(D)-J
awk '$0~/^# V-\(D\)-J/ || ($0!~/^#/ && NF>0) {print}' input_file > parsed_file
一方、ファイルに複数のデータ行が含まれていて、ヘッダーと最初のデータ行のみを印刷したい場合は、コマンドは次のようになりawk
ます。
awk '$0~/^# V-\(D\)-J/ {print} ($0!~/^#/ && NF>0) {print;exit}' input_file > parsed_file
シェルループでこれを行うには、次のようにします。
for file in *LC.fa
do
infile="${file%.*}.fmt7"
outfile="${file%.*}.parsed.txt"
awk '$0~/^# V-\(D\)-J/ || ($0!~/^#/ && NF>0) {print}' "$infile" > "$outfile"
done
または
for file in *LC.fa
do
infile="${file%.*}.fmt7"
outfile="${file%.*}.parsed.txt"
awk '$0~/^# V-\(D\)-J/ {print} ($0!~/^#/ && NF>0) {print;exit}' "$infile" > "$outfile"
done
それぞれ。
ls
ループは、の出力が解析されるにつれてより強力になります。つまり、強くお勧めしません。
awk
コマンドのいくつかの説明
awk
条件が「メイン」プログラムスペースにあり、そのルールがの「条件付きルール」構文に適用されます{ ... }
。
最初の例では、条件と規則があります。
- 逆参照により、行が正規
$0
表現と一致する場合^# V-\(D\)-J
、つまり^
文字列()で始まります。V-(D)-J
- または(
||
)もちろんいいえ#
($0!~/^#/
式)で始まるそしてまた空ではありません。つまり、「フィールド区切り文字」変数で定義されたフィールドが1つ以上あります(NF>0
単純に短縮することもできます)(デフォルトは空白)NF
print
それから行があります。
これにより、ヘッダーと連続したデータ行が印刷されます。
2番目の例では、関連ルールには2つの条件があります。
- 行が文字列で始まる場合はその行です
# V-(D)-J
。print
- 行いいえで始まり
#
、空でないprint
場合はすぐにファイル処理をexit
終了します。awk
このようにして「ヘッダー」が印刷されますが、最初の「データ」行に出会い、印刷されると実行を停止し、各ファイルの最初のデータ行と一緒にヘッダーのみを印刷します。
答え2
forループを設定してsedを呼び出して、解析されたファイルを生成できます。
for f in *LC.fa; do
if=${f%.*}.fmt
of=${f%.*}.parsed.txt
sed -e '
8N;9q
6N;/\n./q;d
' < "$if" > "$of"
done