我有以下代码:
#!/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}'