【问题标题】:printf format specifiers in awk does not work for multiple parametersawk 中的 printf 格式说明符不适用于多个参数
【发布时间】:2017-12-29 19:44:57
【问题描述】:

我正在尝试在名为 example7 的 Bash 中编写程序脚本 它接受作为参数:一个文件名(我们称之为文件 1)和一个列表 数字(下面我们将其称为列表 1),程序需要做的是打印输出的列 通过列表 1 中的数字将它们重新安排到右侧或左侧后的文件 1。(这可以通过使用 awk 的 printf 命令获得)。

例子

假设一个 F1 文件的内容是:

A abcd ddd eee zz tt
ab gggwe 12 88 iii jjj
yaara yyzz 12abcd xyz x y z

通过命令运行程序后:

example7 F1 -8 -7 6 4

输出:

A       abcd      ddd eee
ab      gggwe      12 88
yaara   yyzz   12abcd xyz

在上面的例子中AABCD之间有7个空格,在abcdddd之间 dddeee 之间有 6 个空格 有一个空格。

另一个例子:

通过命令运行程序后:

example7 F1 -8 -7 6 4 5

输出:

A       abcd      ddd eee   zz
ab      gggwe      12  88  iii
yaara   yyzz   12abcd xyz    x

在上面的例子中AABCD之间有7个空格,在abcdddd之间 dddeee 之间有 6 个空格 eeezz 之间有 1 个空格 88iii 之间有 3 个空格 有两个空格,在xyzx之间有4个空格。

我尝试过这样做:

file=$1
shift
awk '{printf "%'$1's\n" ,$1}' $file

但它只适用于一个数字和一个参数,我不知道如何为多个列和多个参数做到这一点.. 任何帮助将不胜感激。

【问题讨论】:

    标签: linux bash shell unix awk


    【解决方案1】:

    为所有剩余参数设置一个awk 变量,然后将其拆分并循环遍历它们。

    file=$1
    shift
    awk -v sizes="$*" '{words = split(sizes, s); for(i = 1; i <= words; i++) printf("%" s[i] "s", $i); print ""; }' "$file"
    

    尝试将 shell 变量直接替换为 awk 脚本通常是错误的。您应该更喜欢使用-v 设置awk 变量,然后使用awk 自己的字符串连接操作,就像我对s[i] 所做的那样。

    【讨论】:

    • 感谢您的回答,我运行了示例 [ex7 F1 -8 -7 6 4 ],除了第一列之外它都有效。第一列的格式不正确,它从其他列中获取单词并进行组合。
    • 循环遍历数组键不一定按顺序进行。我把它改成了一个数字循环。
    • -v words="$#" '{split(sizes, s) = '{words=split(sizes, s)printf("%" s[i] "s", $i) = printf "%*s", s[i], $i 并且当您编写 printf("\n") 时,您正在打印您假设的 ORS 值,"\n",所以只需改用print "",它将打印 ORS 值(加上它非常简单/简单)。此外,您可以编写 {split(sizes, s); for(i = 1; i in s; i++),而不是使用变量 words
    • 我最初使用 NF 而不是 words,其他人编辑了(如果参数少于字段),我同意您的方法更简单。我有一个旧的(可能是坏的)习惯,即明确使用 \n,就像在其他语言中一样,因为 ORS 实际上从来没有别的东西。
    • 您的最后一个表单看起来太容易与for (i in s) 混淆,我试过了,但它没有按顺序处理它们。我将它保留为i &lt;= words,我认为它更清晰。
    猜你喜欢
    • 2016-05-29
    • 2020-10-07
    • 2017-06-14
    • 2017-11-16
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多