Linux awk中的printf格式说明符不适用于多个参数

Linux awk中的printf格式说明符不适用于多个参数,linux,bash,shell,unix,awk,Linux,Bash,Shell,Unix,Awk,我正在尝试用Bash编写一个名为example7的程序脚本 它接受作为参数:一个文件名让我们称之为文件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

我正在尝试用Bash编写一个名为example7的程序脚本 它接受作为参数:一个文件名让我们称之为文件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
example7 F1 -8 -7 6 4 5
输出:

A       abcd      ddd eee
ab      gggwe      12 88
yaara   yyzz   12abcd xyz
A       abcd      ddd eee   zz
ab      gggwe      12  88  iii
yaara   yyzz   12abcd xyz    x
在上面的示例中,A和ABCD之间有7个空格,在ABCD和ddd之间 ddd和eee之间有6个空格和 有一个空间

另一个例子:

通过命令运行程序后:

example7 F1 -8 -7 6 4
example7 F1 -8 -7 6 4 5
输出:

A       abcd      ddd eee
ab      gggwe      12 88
yaara   yyzz   12abcd xyz
A       abcd      ddd eee   zz
ab      gggwe      12  88  iii
yaara   yyzz   12abcd xyz    x
在上面的示例中,A和ABCD之间有7个空格,在ABCD和ddd之间 ddd和eee之间有6个空格 在eee和zz之间有一个空格,在88和iii之间有3个空格 有两个空格,在xyz和x之间有4个空格

我试过这样做:

file=$1
shift
awk '{printf "%'$1's\n" ,$1}' $file
但它只适用于一个数字和一个参数,我不知道如何才能适用于多个列和多个参数。。 任何帮助都将不胜感激。

将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]所做的那样。

将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=$'{splitsizes,s='{words=splitsizes,s和printf%s[I]s,$I=printf%*s,s[I],$i,当您编写printf\n时,您正在打印您假定的ORS值,\n因此只需使用print,它将打印ORS值加上它会稍微简单一点。此外,您可以编写,而不是使用变量字{splitsizes,s;fori=1;i in s;i++我最初使用NF而不是Word,其他人编辑过,如果参数比字段少,我同意您的方法更简单。我有一个旧的,可能是坏的习惯,即显式使用\n,就像在其他语言中一样,因为ORS实际上从来都不是别的东西。您的最后一个表单看起来太简单了为了与s中的for i混淆,我尝试了它,但它没有按顺序处理它们。我将保留它,因为我感谢您的回答,我运行了示例[ex7 F1-8-7 6 4]除第一列外,它可以正常工作。第一列格式不正确,它从其他列中提取单词并进行组合。数组键上的循环不一定按顺序进行。我将其更改为数字循环。-v words=$'{splitsizes,s='{words=splitsizes,s和printf%s[I]s,$i=printf%*s,s[i],$i,当您编写printf\n时,您正在打印您假定的ORS值,\n因此只需使用print,它将打印ORS值,并且它会稍微简单一点。此外,您可以编写它,而不必使用变量字{splitsizes,s;fori=1;i in s;i++我最初使用NF而不是Word,其他人编辑过,如果参数比字段少,我同意您的方法更简单。我有一个旧的,可能是坏的习惯,即显式使用\n,就像在其他语言中一样,因为ORS实际上从来都不是别的东西。您的最后一个表单看起来太简单了为了与s中的for i混淆,我尝试了,但它没有按顺序处理它们。我将按原样保留它