2017-09-22 3 views
1

特定の行の特定の位置でデータファイルを削除したい場合、別のテキストファイルのリストに基づいて、そして私の頭の中でそれを取り戻すために苦労している。sedまたはawk(または同様のもの)をインクリメンタルまたはループで使用して、別のテキストファイルに指定された行番号および位置番号に基づいてデータファイル内の削除を実行する

私はcygwinで作業していて、削除を実行するための(大規模な)データファイル(data_file)と、カラム2の関連する行番号と一致するタブ区切りのテキストファイル(coords_file)これらの行のそれぞれの位置番号を3列目に入力します。

効果的には、次の不完全なsedコマンドに似たことをしようとしています。coords_file $ 2は、coords_fileとcoords_fileの2番目の列から取得した行番号を表します。 $ 3は、削除する行の位置を表します。第coords_fileの最初の行の値を使用してSEDランが関連する行に記入し、位置座標、およびその後使用して再度実行されるようにループまたは繰り返しを含む方法があるかどう

sed -r 's coords_file$2/(.{coords_file$3}).*/\1/' datafile  

思いましてcoords_fileのすべての行の2番目の行からの値など?あるいは、別のアプローチがあるとします。同じ結果を得るためにawkを使用しますか?

awkについては、この質問に対するEd Mortonの応答であるawkコマンドを使って、文字列の一致に基づいてこれらの座標を特定しました:line and string position of grep match

awk 'NR==FNR{strings[$0]; next} {for (string in strings) if ((idx = index($0,string)) > 0) print string, FNR, idx }' strings.txt data_file > coords_file.txt 

は似た何かがインプレースの削除を行うだけではなく、このような単純な検索を組み込むと{if($0=="somehow_reference_coords_file_values_here"){$0=""}のように置き換えるなどのラインを、見つける仕事ができる潜在的に考えていました。しかし、それは私を少し超えています(コーディングの初心者なので、元のコマンドが実際にどのように動作しているかはわかりません。

ファイル例

DATA_FILE

@vandelay.1 
blablablablablablablablablablablabla 
+ 
mehmehmehmehmehmehmehmehmehmehmehmeh 
@vandelay.2 
blablablablablablablablablablablabla 
+ 
mehmehmehmehmehmehmehmehmehmehmehmeh 
@vandelay.3 
blablablablablablablablablablablabla 
+ 
mehmehmehmehmehmehmehmehmehmehmehmeh 

coords_file(タブ区切り)
(カラム1が一致しただけの文字列であり、列2はそれにマッチした行番号であり、カラム3マッチの位置番号です)。

stringID 2 20 
stringID 4 20 
stringID 10 27 
stringID 12 27 

望ましい結果:

@vandelay.1 
blablablablablablab 
+ 
mehmehmehmehmehmehm 
@vandelay.2 
blablablablablablablablablablablabla 
+ 
mehmehmehmehmehmehmehmehmehmehmehmeh 
@vandelay.3 
blablablablablablablablabl 
+ 
mehmehmehmehmehmehmehmehme 

どれガイダンスは多くのおかげでいただければ幸いです! (そして私が言及したように、私はです。このコーディングシーンには初めてのです。そういうものが理解できない場合、または私の質問形式がshonky(または質問自体が初歩的である場合)です)。

乾杯。

mehmehmeh文字は、品質スコアであるため(なお、これはすべて、DATA_FILE blablablaラインならびに2行(すなわちmehmehmeh線)以下同じ位置で識別された文字列を削除するために周りに大規模な作業となっています各サンプル(@vandelay.xx)のblablabla文字に一致します。つまり、本質的にはsed -i 's/string.*//' datafileですが、文字列を識別するたびに同じ削除を2行下で実行します。したがって、上記の質問に、ちょうどその代わりに、すべてのものを行うために簡単にスクリプトが実際にありますならば、私に知らせてください!)

+1

答えは、あなたの記述問題の修正のように見えます....が、これは一回限りの修正を超えている場合、私は本当にあなたが後戻りして修正していただければ幸いですあなたの生産プロセス。あなたがこれを適所に残すと、それはもっと悪化します(個人的な経験/観察から - /)。がんばろう。 – shellter

+0

応答@shelterに感謝します。うん、CWLiuの反応は完璧だった。私はこれが実際にはちょっとしたことだと思っています!しかし、それが進行中のものであれば、それを早めに後退させて修正する方法を理解するだろう;)。乾杯。 –

答えて

2

あなたは単にそれを行うために、1つのライナーawkを使用することができ、

$ awk 'NR==FNR{a[$2]=$3;next} (FNR in a){$0=substr($0,0,a[FNR]-1)}1' coords_file data_file 
@vandelay.1 
blablablablablablab 
+ 
mehmehmehmehmehmehm 
@vandelay.2 
blablablablablablablablablablablabla 
+ 
mehmehmehmehmehmehmehmehmehmehmehmeh 
@vandelay.3 
blablablablablablablablabl 
+ 
mehmehmehmehmehmehmehmehme 

ブリーフ説明、

  • NR==FNR{a[$2]=$3;next}:行番号と列aでマッチング位置マップを作成します。その後、awkdata_fileを処理するために開始します:coords_file
  • (FNR in a)NR==FNRのため、式のこの部分は、唯一のプロセスです。式を使用して、配列aに含まれるFNRを検索します。
  • $0=substr($0,0,a[FNR]-1)$0を切断する行に再割り当てします。
  • 1:印刷は、以下のすべての行
+0

伝説。これは完璧なおかげです。私は申し訳ありません投票の担当者を持っていないが、これはスポットです。 –

+0

詳細な説明もありがとうございます。私はコーディングの背景がないので、この種の説明は実際にコマンド内で実際に何が起こっているのかを理解するのに間違いなく役立ちます。乾杯。 –

+0

ようこそ。喜んでそれが助けることができます。 – CWLiu

関連する問題