首页 > 解决方案 > 如何修剪前导和尾随空格并将其替换为 tab(/t) 以使其从文件的每一行组织起来?

问题描述

我正在使用 Sun solaris 5.10。在我的 shell 脚本中,我将 sql o/p 数据假脱机到 Unix 文件,稍后我使用该文件使用 mailx 发送邮件。我的问题是当 vim 或 cat 在 unix 中的假脱机文件时,数据以 sql o/p 组织。但是,在将其重定向到邮件或将其复制到 Word 文件中以检查数据时,会变得杂乱无章。我希望我的 o/p 与 sql o/p 的顺序相同。

JOB_ID|JOB_NME                 |START_DTE_TIM                 |END_DTE_TIM           |DURATION                      |STATUS
------------|------------------------------|------------------------------|----------------------|------------------------------|------------------------------
           5|J191-JOB1 |18/08/2020 12:37:09 AM        |18/08/2020 12:37:13 AM|4 Seconds                     |SUCCESS
           4|J191-JOB12   |18/08/2020 12:37:09 AM        |                      |                              |FAILED
           1|J190-JOB3   |18/08/2020 12:37:10 AM        |18/08/2020 12:37:14 AM|4 Seconds                     |SUCCESS
           2|J190-JOB15             |18/08/2020 12:37:09 AM        |18/08/2020 12:37:15 AM|6 Seconds                     |SUCCESS

我如何使用 awk、sed 或 trim 来组织文件内容。

标签: unixawksedtrim

解决方案


有趣的是,第二行保留了列大小。因此,您可以读取文件的第二行并从中获取列宽,然后使用该宽度缩进所有其他列。

我将文件保存在名为的文件中a.txt并做了:

# Execute awk with | as separator
$ awk -F'|' '
   # If first file and line number 2
   FNR==NR&&NR==2{
      # save the lengths of all fields in array named s
      for (i=1;i<=NF;++i) s[i]=length($i)
   }
   # if the second file
   FNR!=NR{
        # for each field
        for (i=1;i<=NF;++i) {
           # print the field
           # if the first field (i==1) then format the field to the right,
           # otherwise to the left
           # use the variable length %*s specifier to pass the length as parameter
           printf("%" (i==1?"":"-") "*s%s",
                 # then lenght of the field
                 s[i],
                 # remove leftovers tabs and spaces in front and after values
                 gensub(/^[ \t]*([^ \t].*[^ \t])[ \t]*$/, "\\1", "1", $i), 
                 # if its the last field, print a newline, otherwise print a |
                 i!=NF?"|":"\n");
           }
      # pass the file twice
     }' a.txt a.txt
      JOB_ID|JOB_NME                       |START_DTE_TIM                 |END_DTE_TIM           |DURATION                      |STATUS                        
------------|------------------------------|------------------------------|----------------------|------------------------------|------------------------------
           5|J191-JOB1                     |18/08/2020 12:37:09 AM        |18/08/2020 12:37:13 AM|4 Seconds                     |SUCCESS                       
           4|J191-JOB12                    |18/08/2020 12:37:09 AM        |                      |                              |FAILED                        
           1|J190-JOB3                     |18/08/2020 12:37:10 AM        |18/08/2020 12:37:14 AM|4 Seconds                     |SUCCESS                       
           2|J190-JOB15                    |18/08/2020 12:37:09 AM        |18/08/2020 12:37:15 AM|6 Seconds                     |SUCCESS                       

solaris 的另一个尝试:

awk -F'|' '
FNR==NR&&NR==2{
    for (i=1;i<=NF;++i) s[i]=length($i)
}
FNR!=NR{
    for (i=1;i<=NF;++i) {
        gsub(/^[ \t]*\([^ \t].*[^ \t]\)[ \t]*$/, "\\1", $i)
        if (i == 1) { fmt = "%*s%s"; }
        else { fmt = "%-*s%s"; }
        printf(fmt, s[i], $i, i!=NF?"|":"\n");
    }
}' a.txt a.txt

https://repl.it/@kamilcukrowski/Bash-2


推荐阅读