在bash脚本中使用awk标记字符串

我想逐行读取文件的每一行,调整每一行的内容并进行一些处理。文件结构和脚本如下所示

[root@localhost:~] cat vms.txt
mahmood May 24
[root@localhost:~] cat power_offs2.sh
#!/bin/bash
INPUT=/vms.txt
while IFS= read -r line; do
    echo "$line" | awk '{split($0,a,"|"); print a[1],a[2],a[3]}'
    NAME=a[1]
    NEW_MONTH=a[2]
    NEW_DAY=a[3]
    echo $NAME "-" $NEW_MONTH "-" $NEW_DAY
done < $INPUT

但是输出是

[root@localhost:~] sh /power_offs2.sh
mahmood May 24
a[1] - a[2] - a[3]

似乎数组是在awk范围内定义的。我该如何解决?

评论
xnemo
xnemo

From the input, looks like the text is space delimited. You can use bash read for that

while read name month dd ; do
    printf '%s-%s-%s\n' "$name" "$month" "$dd"
done

输出:

mahmood-May-24
点赞
评论
rut
rut

快速解决:

NAME=$(awk '{print $1}' vms.txt)
NEW_MONTH=$(awk '{print $2}' vms.txt)
NEW_DAY=$(awk '{print $3}' vms.txt)
echo $NAME "-" $NEW_MONTH "-" $NEW_DAY
点赞
评论
sesse
sesse

With awk:

$ awk -v OFS="-" '{$1=$1}1' vms.txt
mahmood-May-24
点赞
评论
Ivy
Ivy

As the OP's determined, the array (a[]) has scope within the awk call and therefore the array cannot be referenced by the calling process.

假设:

  • 输入数据由空格分隔
  • 我们只处理一行输入
  • 解析后的值需要父脚本可以访问

We can eliminate the need for awk, as well as any subprocessing (eg, echo | awk, $(awk ...)) and use a simple read command:

$ cat vms.txt
mahmood May 24

$ read -r NAME NEW_MONTH NEW_DAY < vms.txt

$ echo $NAME "-" $NEW_MONTH "-" $NEW_DAY
mahmood - May - 24
点赞
评论