【问题标题】:awk custom printf command generationawk 自定义 printf 命令生成
【发布时间】:2016-01-21 23:03:02
【问题描述】:

TL;DR - 我有一个看起来像格式说明符 ($TEMP) 的变量,我需要将其与 awk printf 一起使用。

所以通过这样做:

awk '-v foo="$temp" {....{printf foo} else {print $_}}' tempfile1.txt > tmp && mv tmp tempfile1.txt

Bash 应该看到这个:

awk '{.....{printf "%-5s %-6s %...\n", $1, $2, $3....} else {print $_}}' tempfile1.txt > tmp && mv tmp tempfile1.txt

示例输入:

col1        col2           col3
aourwyo5637[dfs]   67tyd 8746.0000
tomsd  - 4
o938743[34* 0 834.92
.
.
.

预期输出:

col1               col2         col3
aourwyo5637[dfs]   67tyd        8746.0000
tomsd              -            4
o938743[34*        0646sggg     834.92
.
.
.

加长版

我是脚本新手,在互联网上搜索了超过 5 个小时并做了我认为是拼凑的信息之后,我遇到了障碍。

场景:

所以我需要在一个目录中打开多个随机表。因为我对给定表一无所知,除了我需要格式化文件第 4 行上的所有数据和第 14 行之后的所有行。

我需要在 awk 中动态创建一个自定义 printf 命令,以便每列的填充等于一个值(比如 5 个空格),因此打开表格后它看起来很漂亮。

这是我目前想出的:

awk '{
        for (i=1;i<=NF;i++) 
        {
            max_length=length($i);
            if ( max_length > linesize[i] ) 
                {
                    linesize[i]=max_length+5;
                }
        }}
        END{
            for (i = 1; i<=length(linesize); i++)
            {
                print linesize[i] >> "tempfile1.txt"    
            }
    }' file1.txt

# remove all blank lines in tempfile1.txt
awk 'NF' tempfile1.txt > tmp && mv tmp tempfile1.txt 
# Get number of entries in tempfile1.txt
n=`awk 'END {print NR}' tempfile1.txt`
# This for loop generates the pattern I need for the printf command
declare -a a
for((i=0;i<$n;i++))
do
    a[i]=`awk -v i=$((i+1)) 'FNR == i {print}' tempfile1.txt`
    temp+=%-${a[i]}s' '
    temp2+='$'$((i+1))', '  
    #echo "${a[$i]}";
    #echo "$sub"
done
temp='"'${temp::-2}'\n", '
# echo "$temp"
temp=$temp${temp2::-2}''
# echo "$temp"

awk <something here>
# Tried the one below and it gave an error
awk -v tem="$temp" '{printf {tem}}

所以理想情况下,我希望 awk 命令看起来像这样,只需将 bash 变量 temp 放在 awk 命令中即可。

所以通过这样做:

awk '-v foo="$temp" {if(FNR >=14 || FNR == 4) {printf foo} else {print $_}}' tempfile1.txt > tmp && mv tmp tempfile1.txt

Bash 应该看到这个:

awk '{if(FNR >=14 || FNR == 4) {printf "%-5s %-6s %...\n", $1, $2, $3....} else {print $_}}' tempfile1.txt > tmp && mv tmp tempfile1.txt

【问题讨论】:

  • 编辑您的问题以包含示例输入和预期输出,以便我们开始为您提供帮助。阅读 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书,与通过谷歌搜索单个结构来学习 awk 相比,您所浪费的时间要少得多。
  • @EdMorton:会查一下你提到的那本书。
  • 你似乎在重塑column -t filename
  • 从您的示例输入和预期输出中删除 ...s,它们只是将其弄乱并使其无法测试。如果您需要向我们传达一些信息,请用一些具体的值替换它们。该示例输入似乎与您声明的I need to format all data that is on line 4 and all lines after line 14 of the file 要求完全无关。想想你的帖子 - 让它简单而一致,这样我们就可以用最少的努力让更多的人愿意尝试理解你想要什么。

标签: bash file-io awk sed grep


【解决方案1】:

听起来这可能是您想要的,但仍然很难从您的问题中看出:

$ cat tst.awk
BEGIN { OFS="   " }
NR==FNR {
    for (i=1;i<=NF;i++) {
        width[i] = (width[i] > length($i) ? width[i] : length($i))
    }
    next
}
{
    for (i=1;i<=NF;i++) {
        printf "%-*s%s", width[i], $i, (i<NF?OFS:ORS)
    }
}

$ awk -f tst.awk file file
col1               col2    col3
aourwyo5637[dfs]   67tyd   8746.0000
tomsd              -       4
o938743[34*        0       834.92

在删除所有虚假的.s 后,我针对您问题中的示例输入运行了它。

【讨论】:

    【解决方案2】:
    # Tried the one below and it gave an error
    awk -v tem="$temp" '{printf {tem}}
    
    • 行尾的' 丢失
    • {tem} 错误;写tem
    • printf,expr-list 丢失了
    • \n 不见了

    更正:

    awk -v tem="$temp" "{printf tem\"\n\", $temp2 0}"
    

    awk "{printf \"$temp\n\", $temp2 0}"
    

    (更简单)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-02
      • 2021-12-11
      • 2022-01-07
      • 2021-12-08
      • 2016-03-29
      • 1970-01-01
      • 2020-07-09
      • 2014-01-20
      相关资源
      最近更新 更多