更改显示 for 循环的形状

更改显示 for 循环的形状

我有以下代码:

#!/bin/bash

FSTAB=` grep -vE "^#|swap|UUID" /etc/fstab  | awk '{print $1,$2,$3}'`

for i in $FSTAB
do

   echo "$i"

done

返回这个:

/dev/mapper/centos-root
/
xfs
/dev/sdb2
/hdos
xfs

问题是,稍后我想比较它,所以我用换行符返回它,并且我希望它在单行中返回而不跳转,也就是说:

/dev/mapper/centos-root / xfs
/dev/sdb2 /hdos xfs

答案1

无论您如何填充FSTAB变量,循环中不带引号的变量扩展for都会消除不同类型空白之间的区别。 (看:什么时候需要双引号?为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?

要解决这个问题,可以设置IFS为仅在换行符上分割,或者使用循环遍历各行while read

$ fstab=$(grep /etc/fstab ...)
$ while IFS= read -r line; do 
    printf "$line\n"
  done <<< "$fstab"

while read -r dev mnt fs; do ...如果您想要将字段放在单独的变量中,也可以使用。

答案2

您的整个变量分配命令链可以在一个中完成,awk而不是通过管道grep将输出传递到awk

FSTAB=` grep -v "^#" /etc/fstab | grep . | grep -v "swap" | grep -v "UUID"   | awk '{print $1,$2,$3}'`

可以改为

FSTAB="$(awk 'NF && $0 !~ /^#|swap|UUID/ {print $1, $2, $3}' /etc/fstab)"

换行符将嵌入到变量中,因此您不需要循环任何内容,只需echo "$FSTAB".

但是,不是解析/etc/fstab成变量然后解析/etc/fstab,直接使用更复杂的脚本进行解析可能会更好,awk该脚本可以准确地处理您当前从中抓取的输出所需的内容。

答案3

只是GNU egrep:

egrep -v "^#|swap|UUID" /etc/fstab  | egrep -o '^(\S*\s*){1,3}'

相关内容