bashで2つのテキストファイルをリンクして、2つの列に一致する出力を取得します。

bashで2つのテキストファイルをリンクして、2つの列に一致する出力を取得します。

これら2つのTXTは、以下のようにBashスクリプトで1つにリンクする必要があります。助けることができます。

学生TXTファイル

123456 John Doe
345678 John P. Doe
987654 John Public Doe

コーステキストファイル

EECS2021 John Doe
EECS2021 John P. Doe
EECS2031 John Doe
EECS4201 John Doe

最終TXTには、その人とその人に割り当てられたプロセスを含める必要があります。たとえば:-

Person          courses
John Doe        EECS2021 | EECS2031 | EECS4201
John P. Doe     EECS2021 
John Public Doe NoCourses

このスクリプトを試しましたが、まだ出力を取得できませんでした。

#!/bin/sh
persons=`cat T1.txt`
courses=`cat T2.txt`
echo "$persons"
echo "$courses"
linecountf1=$(wc -l T1.txt | awk '{print $1}')
linecountf2=$(wc -l T2.txt | awk '{print $1}')
i=1
y=1

echo "$persons" | while read line
do
   name1=$(cat T1.txt | awk -F" " '{print $2" " $3" " $4" " $5" " $6}' | sed -n '$i p')
   while [ $linecountf1 = $linecountf2 ]
   do
        name2=$(cat T2.txt | awk -F" " '{print $2" " $3" " $4" " $5" " $6}' | sed -n '$y p')
        if [ "$name1" = "$name2" ]
                then
                        echo "It matching"
                        gdc=$(cat T2.txt | awk -F" " '{print $1}' | sed -n '$i p')
                fi
   done
done



echo "John Doe Registered courses - $gdc"
echo "John P. Doe Registered courses -"
echo "John Public Doe Registered courses -"

ありがとう

ベストアンサー1

出力順序が重要でない場合は、次のawkプログラムが機能するはずです。

awk 'FNR==NR{sub(/^[^ ]* +/,""); courses[$0]; if (length($0)>max) max=length($0); next}
     {course=$1; sub(/^[^ ]* +/,"");
      if (courses[$0]) courses[$0]=courses[$0] " | " course; else courses[$0]=course}
     END{
       printf "%- *s Courses\n",max, "Person";
       for (p in courses) {printf "%- *s %s\n",max,p,courses[p] ? courses[p] : "NoCourses"}
     }' students.txt courses.txt 

入力例の場合、GNUは以下を生成しますawk

Person          Courses
John Public Doe NoCourses
John P. Doe     EECS2021
John Doe        EECS2021 | EECS2031 | EECS4201

説明する

  • 最初のファイル(FNRファイル別の行カウンターとして表示され、グローバル行カウンターと同じ)を処理するときは、「index」が生徒名であり、値は空のNR配列を埋めるだけです。coursesこれを行うには、sub()行から生徒IDを削除する機能を使用して生徒名のみを残します($0現在は生徒名のみを含む)。学生名にはスペースを含めることができるため、通常、「スペース内の「フィールドの分割」は名前の抽出には役立ちません。

    maxまた、後で出力をきれいにするために、最も長い名前の長さを記録してください。

  • 2番目のファイルを処理するときは、学番(最初のスペースで区切られたフィールド)を一時変数に保存し、生徒名のみが残るように行からcourse再度削除します。次に、配列内の生徒名を探しcourses、関連する値がすでに存在する場合(つまりcourses[$0]空でない場合)、既存の値にコース名を区切りに追加します|。それ以外の場合は、値を現在のコース名に設定します。

  • 2つのファイル(条件END)を処理した後、最長の生徒名に対応するように書式設定された列ヘッダーを印刷し、生徒のコース配列を繰り返し、各項目の生徒名と関連講座を印刷します(for (p in courses)すべての「配列インデックス」= inで繰り返すことを意味します)。学生名の場合courses、出力順序を保証できない部分です。バージョンによって異なりますawk

おすすめ記事