0

I have the following code:

#!/bin/bash

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

for i in $FSTAB
do

   echo "$i"

done

return this:

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

The problem is that later I want to compare it, so I am returning it with line breaks and I want it to be returned in a single line without jumps, that is to say:

/dev/mapper/centos-root / xfs
/dev/sdb2 /hdos xfs
ortiga
  • 131
  • 7
  • for [...]; done | tr -d '\n'. – DopeGhoti Jan 30 '19 at 21:23
  • You'd better let us know what you are compare it to later (or even better, what the overall issue is that you're trying to solve). It may not be needed to output anything at all. In fact, the safest way to store the pathnames for later use would be in an array. That would enable you to handle pathnames with whitespaces and other funky names. – Kusalananda Jan 30 '19 at 21:26
  • Not an answer but your FSTAB could be reduced to: grep -vE "^#|swap|UUID" /etc/fstab | awk '{print $1,$2,$3}' – jesse_b Jan 30 '19 at 21:32
  • 1
    Or awk '$0 ! ~ /^#|swap|UUID/ {print $1, $2, $3}' /etc/fstab. – DopeGhoti Jan 30 '19 at 21:33
  • And also the output you are looking for would be achieved from simply removing the loop altogether and echoing the contents of FSTAB – jesse_b Jan 30 '19 at 21:33
  • 1
    Or letting awk write to stdout (: – DopeGhoti Jan 30 '19 at 21:34
  • 1
    My life got a lot easier (and involved a lot fewer pipe fittings) the day I realized that grepping into awk is a kissing cousin to the Useless Use of Cat. – DopeGhoti Jan 30 '19 at 21:42
  • then I want to compare it with the output of this command mount | grep -e "^ /" | awk '{print $ 1, $ 3, $ 5}' – ortiga Jan 30 '19 at 21:53
  • line by line......... – ortiga Jan 30 '19 at 21:53
  • diff < <(awk '$0 ! ~ /^#|swap|UUID/ {print $1,$2,$3}' /etc/fstab) < <(mount | awk '$0 ! ~ /^ /{print $1,$3,$5}') – jesse_b Jan 30 '19 at 22:07

3 Answers3

2

Your entire variable assignment command chain there can be done in one awk rather than piping grep's output into awk:

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

can instead be

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

Newlines will be embedded in the variable, so you don't need to loop anything, you can simply echo "$FSTAB".

However, rather than parsing /etc/fstab into a variable and then parsing that, it would probably be better to parse /etc/fstab directly with a more involved awk script that does exactly what you need to with the output you're currently scraping from it.

DopeGhoti
  • 76,081
2

Regardless of how you fill the FSTAB variable, the unquoted expansion of it in the for loop removes the distinction between different kinds of white space. (See: When is double-quoting necessary? and Why does my shell script choke on whitespace or other special characters?)

To work around that, either set IFS to split only on newlines, or loop over the lines with a while read loop:

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

You could also use while read -r dev mnt fs; do ... if you wanted the fields in separate variables.

ilkkachu
  • 138,973
0

Just GNU egrep:

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