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
10
  • for [...]; done | tr -d '\n'.
    – DopeGhoti
    Commented Jan 30, 2019 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
    Commented Jan 30, 2019 at 21:26
  • 1
    Or awk '$0 ! ~ /^#|swap|UUID/ {print $1, $2, $3}' /etc/fstab.
    – DopeGhoti
    Commented Jan 30, 2019 at 21:33
  • 1
    Or letting awk write to stdout (:
    – DopeGhoti
    Commented Jan 30, 2019 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
    Commented Jan 30, 2019 at 21:42

3 Answers 3

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.

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.

0
0

Just GNU egrep:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .