File1とFile2を比較して、File2で一致するパターンをコメントアウトします。

File1とFile2を比較して、File2で一致するパターンをコメントアウトします。

テスト名を含むリストファイルが2つあります。 1つのファイルにはデフォルトのテスト名が含まれています(例:)。usb30_tb_7_10他のファイルには'include "usb30_tb_7_10.sv".I want to get all names (すべての名前を取得したい)リスト`これはデフォルト名(または.svを除く)で、次の場所で検索します。リスト2行全体をコメントアウトします。

つまり:

リスト1

test1
test3

コメントする前にリスト2

'include "test1.sv"
'include "test2.sv"
'include "test3.sv"
'include "test4.sv"

比較後のリスト2

//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
'include "test4.sv"

私はgrep / sed / awkを初めて使用していましたが、まだ解決策が見つかりませんでした。

awkが特定のパターンを入力として使用することに関する回答を見ましたが、それほど役に立ちませんでした。

私は以下を試してみます:

awk '-include list1.lst {print "// " $0; next} 1' list2.sv

しかし、うまくいきません。

答え1

awkを使用してください:

$ awk -F'[".]' 'NR==FNR{a[$0]; next} $2 in a{$0="//"$0} 1' list1 list2
//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
'include "test4.sv"

仕組み:

  • -F'[".]'

    "これはawkに、または発生時にフィールドを区別するように指示します.

  • NR==FNR{a[$0]; next}

    最初のファイルを読み取ると、これはlist連想配列のa現在の行と同じキーを生成し、残りのコマンドをスキップしてその行nextにジャンプするようにawkに指示します。

    詳細:NRawkがこれまでに読んだ行の総数。 FNR現在のファイルからこれまでに読み込んだ行数です。この時点で、FNR==NR私たちは最初のファイルを読んでいます。

  • $2 in a{$0="//"$0}

    2番目のファイルを読み取ると、現在の行の2番目のフィールドが連想配列のキーである場合は、行の先頭に追加するように//awkに指示しますa

  • 1

    これはprint-the-lineのawkの神秘的な速記です。

拡張例

コメントに記載されている追加の行を使用してください。

$ cat list1
test1
test3
usb30_suspend_resume
$ cat list2
'include "test1.sv"
'include "test2.sv"
'include "test3.sv"
'include "usb30_suspend_resume.sv"
'include "test4.sv"
$ awk -F'[".]' 'NR==FNR{a[$0]; next} $2 in a{$0="//"$0} 1' list1 list2
//'include "test1.sv"
'include "test2.sv"
//'include "test3.sv"
//'include "usb30_suspend_resume.sv"
'include "test4.sv"

Pastebin ファイルの適用

Pastebinのファイルにはlist1に末尾のスペースがあり、両方のファイルにWindowsスタイルの行末があります。この形式を処理するには、次のようにします。

awk 'NR==FNR{a[$1]; next} $2 in a{$0="//"$0} 1' FS='[[:space:]]' list1.txt FS='[".]' list2.txt

答え2

正直なところ、これまでに提供されたスクリプトソリューションを入力するのにかかる時間よりも短い時間で、Vimで対話的にこれを行います。

vim list2

次に、上部のlist1を読んでください。 (list2が終了してlist2が始まる位置を視覚的に簡単に確認できると仮定するので、あらかじめ何も表示する必要はありませんが、必要に応じて:1k alist2の元の行1を最初に表示できます。)

:0r list1

このコマンドを実行すると、カーソルがファイルの先頭の最初の単語に置かれますtest1

*カーソルの下にある単語の次のインスタンスに移動するには、このキーを押します。 (この行はあなたが注釈を付けたい行になります。)

キーを押して挿入モードに入り(小文字の代わりに大文字をI使用するため、行の空白ではなく最初の文字から)を入力してから、Escapeを押します。I//

nクエリの次のインスタンスに移動するには、このキーを押します。 (文字の次の行の先頭にあるので、//カーソルが見つけたばかりのインスタンスに移動します。したがって、次のインスタンスに移動するにはもう一度クリックします。)

1つのインスタンスにのみコメントを付けることができると仮定すると、ファイルの先頭、つまり最初の行に戻ります。下に移動するには、キーを押しますj。または、次の行の空白ではなく最初の文字に移動するには、Enterキーを押します。この場合、結果は同じです。

現在カーソルがあるインスタンスなので、*次のインスタンスに移動するにはタップします。test3

.「行コメント」の操作を繰り返すには押します。 ポイントオーダーは素晴らしいです。 :)

もう一度押してくださいn。 (2回)サンプルテキストではこれで完了です。 2番目の行に戻りますtest3。コメントを付ける必要がある行がさらにある場合は、もう一度入力してくださいj*.nn。何か他のものがあればj*.nnもう一度入力してください。

操作が完了したら(test3使用中の最後の行list1、元の最初の行のすぐ上list2dgg、現在の行からファイルの最初の行まですべての行を削除して、list1その項目がそこに表示されないようにします。これ以上。

全体的に入力しました。

vim list2<Enter>

ファイルを開き、次の操作を行います。

:0r list1<Enter>
*I//<Esc>nn
j*.nn
j*.nn
j*.nn
(Repeat however many times)
dgg

次に保存して終了するには、次のように入力して:xEnterを押します。


編集する:

あなたの「list1」が大きいことを知っています。それは問題ではありません。ただマクロを使用してください。

上記の作業を数回実行して、正しく機能していることを確認したら、次のように入力します。

qkj*.nnq

これはj*.nnレジスタにマクロとして書き込まれますk

と入力してマクロを実行します@k

もう一度実行するにはEnterを押します@@

次に、run it 4000 timesと入力します4000@@。しかし、個人的に私は小さな部分に分けてやりたいです。マクロで点コマンドを使用する代わりに明示的に入力することもできますI//<Esc>

ポイントは私がしますまだ対話的に行うことができます。まだ処理しなければならない行数がいくら多くても1~2分しかかかりません。 Vimの魔法。 :)

答え3

アルゴリズムは次のとおりです。

 for each line of List2
     if line matches ANY pattern in List1 then
         print //line
     else
         print line

bash(または同様の)の実装は次のとおりです。

 while read line ;do
     if echo $line | fgrep -f List1 >/dev/null ;then
         echo "//$line"
     else
         echo "$line"
     fi
 done < List2

関連情報