【问题标题】:Reformating data with awk command depending on a if condition根据 if 条件使用 awk 命令格式化数据
【发布时间】:2025-11-27 16:35:02
【问题描述】:

我有一个脚本可以在目标文件中重新格式化源文件的内容。 它对目录中的每个文件都执行此操作。

这是一个源文件示例:

TABLE;APGFPOLI;
Contrat;CHAR(16);Numéro du contrat
Libelle;CHAR(30);Libellé du contrat
DtCreation;CHAR(8);Date de création
DtMaj;CHAR(8);Date de dernière MAJ
DtEffet;CHAR(8);Date d'effet adhésion
MotifAdh;CHAR(2);Motif d'adhésion
DtRadiation;CHAR(8);Date de radiation
DtEnrRad;CHAR(8);Date enregistrement radiat
MotifRad;CHAR(2);Motif de radiation
MtPrime;Numérique 8.2;Montant prime d'origine
DtEffetSusp;CHAR(8);Date d'effet de suspension
DtFinSusp;CHAR(8);Date de fin de suspension
MotifSusp;CHAR(2);Motif de suspension
DestBord;CHAR(1);Destinataire du bordereau
CdDest;CHAR(5);Code du destinataire
NivRupBord;CHAR(1);Niveau rupture bordereau
BordCETIP;CHAR(1);Bordereau CTIP
EnvBordNom;CHAR(1);Envoi bordereau nominatif
Indice;CHAR(2);Indice appliqué
Echeance;CHAR(2);Echéance de l'indice (MM)
Effectif;CHAR(5);Effectif
CdRegr;CHAR(3);Code regroupement 1
CdGroupe;CHAR(3);Code regroupement 2
Periodicite;CHAR(1);Périodicité
Terme;CHAR(1);Terme
Produit;CHAR(6);Code produit affecté
Inspecteur;CHAR(5);Inspecteur
CleInsp;CHAR(1);Clé inspecteur
Filler;CHAR(6);Filler

这里是shell生成的目标文件:

01 APGFPOLI.

   * Numéro du contrat.

     05 Contrat PIC X(16).

   * Libellé du contrat.

     05 Libelle PIC X(30).

   * Date de création.

     05 DtCreation PIC X(8).

   * Date de dernière MAJ.

     05 DtMaj PIC X(8).

   * Date d'effet adhésion.

     05 DtEffet PIC X(8).

   * Motif d'adhésion.

     05 MotifAdh PIC X(2).

   * Date de radiation.

     05 DtRadiation PIC X(8).

   * Date enregistrement radiat.

     05 DtEnrRad PIC X(8).

   * Motif de radiation.

     05 MotifRad PIC X(2).

   * Montant prime d'origine.

     05 MtPrime Numérique 8.2.

   * Date d'effet de suspension.

     05 DtEffetSusp PIC X(8).

   * Date de fin de suspension.

     05 DtFinSusp PIC X(8).

   * Motif de suspension.

     05 MotifSusp PIC X(2).

   * Destinataire du bordereau.

     05 DestBord PIC X(1).

   * Code du destinataire.

     05 CdDest PIC X(5).

   * Niveau rupture bordereau.

     05 NivRupBord PIC X(1).

   * Bordereau CTIP.

     05 BordCETIP PIC X(1).

   * Envoi bordereau nominatif.

     05 EnvBordNom PIC X(1).

   * Indice appliqué.

     05 Indice PIC X(2).

   * Echéance de l'indice (MM).

     05 Echeance PIC X(2).

   * Effectif.

     05 Effectif PIC X(5).

   * Code regroupement 1.

     05 CdRegr PIC X(3).

   * Code regroupement 2.

     05 CdGroupe PIC X(3).

   * Périodicité.

     05 Periodicite PIC X(1).

   * Terme.

     05 Terme PIC X(1).

   * Code produit affecté.

     05 Produit PIC X(6).

   * Inspecteur.

     05 Inspecteur PIC X(5).

   * Clé inspecteur.

     05 CleInsp PIC X(1).

   * Filler.

     05 Filler PIC X(6).

我想做的是改变那条线:

MtPrime;Numérique 8.2;Montant prime d'origine

像这样:

05 MtPrime PIC 9(8).v9(2)。

如您所见,PIC 9(X).v9(Y) 更改了“Numérique X.Y”。

条件是如果我在“Numerique”之后只有一个数字“X”,我需要像这样重新格式化它:

“图 9(X)”

但如果我有一个数字“X”点另一个数字“Y”,我需要这样打印:

“PIC 9(X).v9(Y)”

使用 awk 命令并且作为一个完整的初学者,我不知道如何实现这一点。

这是我的外壳:

#!/bin/bash

SOURCE_DIRECTORY="/home/yha/AG2R/SOURCE/*"
TARGET_DIRECTORY="/home/yha/AG2R/COPY/"

for f in $SOURCE_DIRECTORY 
do 
    b=$(basename "$f")
    echo "Processing $f file.."; 
    awk -F ';' '$1=="TABLE" && $3=="" {printf "01 %s.\n\n", $2; next} {sub(/CHAR/,"PIC X", $2);printf "   * %s.\n\n     05 %s %s.\n\n", $3, $1, $2;}' "$f" > "$TARGET_DIRECTORY/$b.cpy"
done 

【问题讨论】:

  • 您是否尝试自己解决此问题?如果是,您尝试了什么,遇到了什么困难?否则,您不认为学习一点 awk 并开始尝试自己解决编程问题会更好吗?这当然不会浪费时间。
  • 我尝试做与“TABLE”更改相同的事情,但使用“Numérique”一词。真正的问题更多的是仅仅改变原始值的条件
  • 我将此添加到我的 awk 命令中:{sub(/Numérique/,"PIC 9", $2);} 但我的输出没有任何变化,我不知道我能做些什么来改进它
  • 请不要在 cmets 中回答。编辑您的问题,显示您使用的确切 awk 脚本,显示输出内容并解释其不正确的原因。
  • 请提供minimal reproducible example。请记住,我们不知道您在做什么,不要假设任何事情。目前,您发布的代码不会根据源文件示例生成您显示的目标文件。

标签: bash shell unix awk


【解决方案1】:

对于awk 部分,您可以使用正则表达式来检查后跟数字的单词以及带有点和数字的可选部分。

^Numérique [0-9]+(\.[0-9]+)?$

如果匹配,您可以在空格或点上分割。然后,您可以通过检查数组中是否存在具有拆分值的第三个条目来组装要打印的字符串,并以第二个值的值开始字符串。

数据

$cat file
TABLE;APGFPOLI;
DtEnrRad;CHAR(8);Date enregistrement radiat
MotifRad;CHAR(2);Motif de radiation
MtPrime;Numérique 8.2;Montant prime d'origine
MtPrime;Numérique 5;Montant prime d'origine
DtEffetSusp;CHAR(8);Date d'effet de suspension

awk 脚本

awk -F ';' '
$1=="TABLE" && $3=="" {
  printf "01 %s.\n\n", $2;
  next
}
{
  result = $2
  if ($2 ~ /^Numérique [0-9]+(\.[0-9]+)?$/) {
    nr=split($2,a,"[ .]")
    result = "PIC 9(" a[2] ")"
    if (nr == 3) {
      result = result ".v9(" a[3] ")"
    }    
  }
  sub(/CHAR/,"PIC X", result);
  printf "   * %s.\n\n     05 %s %s.\n\n", $3, $1, result;
}' file

输出

01 APGFPOLI.

   * Date enregistrement radiat.

     05 DtEnrRad PIC X(8).

   * Motif de radiation.

     05 MotifRad PIC X(2).

   * Montant prime d'origine.

     05 MtPrime PIC 9(8).v9(2).

   * Montant prime d'origine.

     05 MtPrime PIC 9(5).

   * Date d'effet de suspension.

     05 DtEffetSusp PIC X(8).

【讨论】: