txtファイルの特定の場所にあるデータを別のファイルのデータに置き換える

txtファイルの特定の場所にあるデータを別のファイルのデータに置き換える

次の形式のテキストファイルがあります。

$data This is the experimental data    
good data
This is good file
datafile
1 4324 3673 6.2e+11 7687 67576
2 3565 8768 8760 5780 8778          "This is line '2'"
3 7656 8793 -3e+11 7099 79909
4 8768 8965 8769 9879 0970
5 5878 9879 7.970e-1 9070 0709799
.
.
.
100000 3655 6868 97879 96879 69899
$.endfile

行「2」から「100000」までの3番目と4番目の列のデータを、それぞれ1列と99999行で構成される2つの異なるテキストファイルのデータに置き換えたいと思います。

awkこれを行うには、他のUNIXコマンドをどのように使用しますかsed?列区切り記号は空白です。

他の2つのテキストファイルはそれぞれ99999行で構成され、フォーマットは次のとおりです。

12414
12421
36347
3.4e+3
-3.5e22
987983
.
.
.
87698

ベストアンサー1

奇妙な方法:

awk '{if(FNR==NR){f2[FNR+1]=$1;} 
      else{
        if(FNR==1){k++;} 
        if(k==1){f3[FNR+1]=$1} 
        else{if($1~/^[0-9]+/ && $1>1){$3=f2[$1];$4=f3[$1];} 
         print}
  }}' file2 file3 file1 

明確にするために、これはコメントスクリプトで書かれたものと同じです。

#!/usr/local/bin/gawk -f

{
    ## NR is the current line number, irrespective of 
    ## which input file is being read. FNR is the line 
    ## number of the current file. It is reset to 1 each 
    ## time a new file is opened. Therefore, FNR will be 
    ## equal to NR only while the 1st file is being read.
    if(FNR==NR){
        ## If this is the 1st file, save its 1st field
        ## in the array f2. The key of the array is the
        ## line number of the current file plus one. This is
        ## because you want to start modifying from row '2' onwards.
        ## Therefore, presumably, you want the 1st row of file2 to
        ## be the value for row '2' of your data file..
        f2[FNR+1]=$1;
    } 
    ## If this is not the 1st file
    else{
        ## If this is the 1st line of the current file
        if(FNR==1){
            ## Increase the value of the variable k by 1.
            k++;
        } 
        ## If k is currently 1, this means that the above has only
        ## been run once so we are currently reading the 1nd file.
        if(k==1){
            ## Save the 1st field of this file (file3 in your example)
            ## in the array f3. The key of the array is the
            ## line number of the current file plus one. 
            f3[FNR+1]=$1
        }
        ## If k is not 1, we are reading the 3rd file. In this case, 
        ## your actual data.
        else{
            ## If the 1st field is a number and is greater than 1.
            ## In other words, if this is one of the lines you want
            ## to change. 
            if($1~/^[0-9]+/ && $1>1){
                ## Set the 3rd field to be the value saved in the array
                ## f2 for the value of $1.  
                $3=f2[$1];
                ## Set the 4th field to be the value saved in the array
                ## f3 for the value of $1. 
                $4=f3[$1];
            } 
            ## Print the current line. Since this is outside the
            ## previous if block, it will print all lines irrespective
            ## of whether they've been modified. 
            print;
        }
    }
}

パール方式:

perl -lane 'BEGIN{
    open(A,"file2"); while(<A>){chomp; $f2{$.+1}=$_;} 
    open(B,"file3"); while(<B>){chomp; $f3{$.+1}=$_;}} 
    if($F[0]=~/^\d+$/ && $F[0]>1){$F[2]=$f2{$F[0]}; $F[3]=$f3{$F[0]}}
     print "@F"' file1

説明する

  • -lanel各入力行の末尾から末尾の改行を自動的に削除し(と同じ)、chomp各ステートメントに改行を追加します。空のスペースの各入力行は自動的に配列に分割され、Perlはawkのように実行されますprint。 「入力ファイルの各行に提供されているスクリプトを実行します。a@Fn-e
  • BEGIN{...}:入力ファイルを読み込む前に実行されます。この例では、各追加ファイルを開き、その内容をハッシュに保存し%f2ます%f3。これはawk基本的に上記で使用したものと同じ配列です。
  • if($F[0]=~/^\d+$/ && $F[0]>1){...}:もう一度言うが、これはawkスクリプトと同じ論理です。このフィールドは、各ファイルに対応するエントリに置き換えられます。
  • print "@F":すべてのフィールドが印刷されます。

おすすめ記事