|
次のように、2つのタイプのフィールド区切り文字を持つレコード(行)を含むファイルがあります!
。
Name|Age|Physics|Chemistry|Maths|English|Batch!Year!AdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS!2021!1001!A!75
Student2|72|63|60|50|75|EWS!2021!1002!A!85
Student3|72|63|60|50|75|EWS!2021!1002!A!85
以下に提供されているBatch
、Year
およびフィールドをマージする方法は何ですかAdmisnNo
?
簡潔さのために便利なフィールドの小さなサブセットを表示しますが、実際のファイルには関連フィールドがたくさんあります。 2〜3つのマーカーを削除したい!
フィールドは最後のフィールドではなく、合計49フィールドのいずれか(6または7)のフィールドにすることができます。
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
懇願しますawk
が、合理的な標準注文は大歓迎です。
答え1
$ awk -F '|' 'BEGIN { OFS = FS } { sub("!", "", $NF); sub("!", "", $NF) }; 1' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
これは、入力した最後の区切りフィールドから最初の2文字を削除するために使用されますawk
。!
|
NF
コードで任意の数値置換を使用すると、awk
最後のフィールドを除く他のフィールドに影響を与える可能性があります。
最後のフィールドにのみ!
文字が含まれていると仮定した場合は、次のようにしますsed
。
$ sed -e 's/!//' -e 's///' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
!
これにより、各行の最初の項目が削除されます。次に、2!
回目の削除中にまったく同じ交換を2回目に実行します。
!
各行を反転し、3行目を連続して2回削除し、結果の行を再度反転します。これにより、他の|
区切りフィールドにも!
文字を含めることができます。
$ rev file | sed -e 's/!//3' -e 's///3' | rev
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
答え2
$ cat in | while read -r line ; do line="${line/\!/}" ; echo "${line/\!/}"; done
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
答え3
4番目の引数としてGNU awkを使用してくださいsplit()
。
$ awk '{n=split($0,f,/[|!]/,s); s[7]=s[8]=""; for (i=1;i<=n;i++) printf "%s%s", f[i], s[i]; print ""}' file
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
答え4
これは、sed
フィールドを分割せずに7番目のフィールドを次のフィールドとマージするのに適しています。
sed -E 's/|\|!//7' file
再実行すると、7番目の項目(元の8番目の項目)が次の項目とマージされます。完全に:
sed -Ee 's/|\|!//7' -Ee 's/|\|!//7' file
またはより短いです(Philipposによって提案されています)。最初の置換が行われると、2番目の置換が発生するためです。
sed -E 's/\||!//7;s///7' file
-E
移植性(つまり拡張正規表現)にも使用されます。
出力:
Name|Age|Physics|Chemistry|Maths|English|BatchYearAdmisnNo!Grade!Score
Student1|81|65|70|80|88|EWS20211001!A!75
Student2|72|63|60|50|75|EWS20211002!A!85
Student3|72|63|60|50|75|EWS20211002!A!85
ちなみに、最初の置換以降、8番目のフィールドが7番目のフィールドになったため、7
再利用します。それはまるでsed '' file | sed ''
。
また、ここにあるさまざまなフィールド区切り文字は便利で、ほぼすべての隣接フィールドをマージするように調整できます。