1

We want to comment the specific line in fstab file that contained the relevant UUID number

Example:

Disk=sde
UUID_STRING=`  blkid | grep $Disk | awk '{print $2}' `
echo $UUID_STRING
UUID="86d58af9-801b-4c25-b59d-80b52b4acc61"

sed -e "/$UUID_STRING/ s/^#*/#/" -i /etc/fstab

but from /etc/fstab , the line - UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /data/sde ext4 defaults,noatime 0 0 - not commentated

more /etc/fstab

UUID=cb47ad8e-5b90-4ddc-97f5-2c0fa1f1b7e7 /data/sdc ext4 defaults,noatime 0 0 UUID=169da708-3c48-4306-beba-95dab722d3ab /data/sdd ext4 defaults,noatime 0 0 UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /data/sde ext4 defaults,noatime 0 0 UUID=640e2c41-d5c6-4e02-beb9-714ec99e16e2 /data/sdf ext4 defaults,noatime 0 0 UUID=58a8cddf-7ce9-431c-bb71-f4f44c8d62a5 /data/sdg ext4 defaults,noatime 0 0 UUID=6779c108-f74b-4a05-8faf-cf8752844c53 /data/sdh ext4 defaults,noatime 0 0 UUID=3c2352f6-df8e-4b14-b6c0-60caaef0dce0 /data/sdi ext4 defaults,noatime 0 0 UUID=ba59e473-d856-4c8b-a3be-4bfc40009f0d /data/sdb ext4 defaults,noatime 0 0

is it possible to ignore the --> " ? in sed command - sed -e "/$UUID_STRING/ s/^#*/#/" -i /etc/fstab

other solution could be as

 uuid_capture=`  echo $UUID_STRING | sed s'/"/ /g' | awk '{print $NF}' `
 sed -e "/$uuid_capture/ s/^#*/#/" -i /etc/fstab

more /etc/fstab

UUID=cb47ad8e-5b90-4ddc-97f5-2c0fa1f1b7e7 /grid/sdc ext4 defaults,noatime 0 0 UUID=169da708-3c48-4306-beba-95dab722d3ab /grid/sdd ext4 defaults,noatime 0 0 #UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /grid/sde ext4 defaults,noatime 0 0 UUID=640e2c41-d5c6-4e02-beb9-714ec99e16e2 /grid/sdf ext4 defaults,noatime 0 0 UUID=58a8cddf-7ce9-431c-bb71-f4f44c8d62a5 /grid/sdg ext4 defaults,noatime 0 0 UUID=6779c108-f74b-4a05-8faf-cf8752844c53 /grid/sdh ext4 defaults,noatime 0 0 UUID=3c2352f6-df8e-4b14-b6c0-60caaef0dce0 /grid/sdi ext4 defaults,noatime 0 0 UUID=ba59e473-d856-4c8b-a3be-4bfc40009f0d /grid/sdb ext4 defaults,noatime 0 0

yael
  • 13,106

4 Answers4

3

The only issue with your code is that your variable contains the UUID in double quotes, while the UUID in /etc/fstab is not in quotes.

Suggestion: Use the export output format of blkid which exists to allow you to eval the output, which would set the relevant shell variables, for example UUID. Then use $UUID in your sed command.

eval "$( blkid -o export /dev/"$Disk" )"

sed -i '/^UUID='"$UUID"'/ s/^/#/' /etc/fstab

This would find the line(s) that starts with UUID= followed by your UUID string. Those lines would have a # character prepended to the start.

Since the initial pattern is anchored to the start of the line, this also avoids adding the # character more than once if you re-run the command.

The -e option is not needed when only giving sed a single expression, and -i is commonly given before the editing expression(s).

You could also use GNU awk like so:

awk -i inplace -v uuid="$UUID" '$1 == "UUID=" uuid { $0 = "#" $0 }; 1' /etc/fstab

... which would have the same effect given the data that you present. It uses the inplace source module, available since GNU awk 4.1.0, to perform an in-place edit in much the same was as sed -i does it (see also How to change a file in-place using awk? (as with "sed -i")).

The actual code compares the first field with UUID= followed by our UUID string, and if there is a match, the line is modified by adding a # to the start. All lines, whether modified or not, are then printed (outputted to the output file).

This is all assuming that you can't work directly on /etc/fstab using $Disk with something like

sed -i '\|^UUID=.* /data/'"$Disk"' | s/^/#/' /etc/fstab

or

awk -i inplace -v disk="$Disk" '!/^#/ && $2 == "/data/" disk { $0 = "#" $0 }; 1' /etc/fstab

In all cases above, the comment character # could be any string, for example ###FAULTY_DISK###.

Kusalananda
  • 333,661
  • Why this complexity with different quotes like '/^UUID='"$UUID"'/ s/^/#/'? Wouldn't simple "/^UUID=$UUID/ s/^/#/" work just as well? – Ruslan Jan 26 '22 at 09:45
  • @Ruslan If you think it's simpler, then go for it. Personally, I prefer to keep the static parts of the expression in single quotes. It becomes more useful to do so when you start forgetting how backslash is treated differently in single vs. double quotes, or when you want to include literal $ in expressions that also contain variable expansions. But for this simple case, use whichever style works for you. – Kusalananda Jan 26 '22 at 09:54
2

EDIT 2: I just noticed your UUID_STRING variable is UUID="86d58af9-801b-4c25-b59d-80b52b4acc61" instead of only the UUID string. I would first suggest making the variable contain only the UUID string by using the option -F\" to tell awk to use " as the field separator:

UUID_STRING="$( blkid | grep $Disk | awk -F\" '{print $2}' )"
echo $UUID_STRING
86d58af9-801b-4c25-b59d-80b52b4acc61

Once you've done the above, I think the most straightforward way to comment that fstab line would be: sed "s/^.*$UUID_STRING/#&/" /etc/fstab. (note: my original answer had single quotes which is incorrect for variable expansion).

^.*$UUID_STRING will include the beginning of the line with the match and #& will prepend it with #.

sed "s/^.*$UUID_STRING/#&/" /etc/fstab
UUID=cb47ad8e-5b90-4ddc-97f5-2c0fa1f1b7e7 /data/sdc ext4 defaults,noatime 0 0
UUID=169da708-3c48-4306-beba-95dab722d3ab /data/sdd ext4 defaults,noatime 0 0
#UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /data/sde ext4 defaults,noatime 0 0
UUID=640e2c41-d5c6-4e02-beb9-714ec99e16e2 /data/sdf ext4 defaults,noatime 0 0
UUID=58a8cddf-7ce9-431c-bb71-f4f44c8d62a5 /data/sdg ext4 defaults,noatime 0 0
UUID=6779c108-f74b-4a05-8faf-cf8752844c53 /data/sdh ext4 defaults,noatime 0 0
UUID=3c2352f6-df8e-4b14-b6c0-60caaef0dce0 /data/sdi ext4 defaults,noatime 0 0
UUID=ba59e473-d856-4c8b-a3be-4bfc40009f0d /data/sdb ext4 defaults,noatime 0 0

If you're sure it works, add the -i option to overwrite the original file.

fuzzydrawrings
  • 1,656
  • 5
  • 12
  • If you have grep and awk in the same pipeline, you can often combine them: awk -v disk="$Disk" -F '"' '$0 ~ disk { print $2 }'. In this case, though, it may possibly be enough to tell blkid to look at a particular path under /dev and then just pull out the second field from that. – Kusalananda Jan 25 '22 at 22:12
  • True. My aim was to change as little of OP's code as necessary to get the output he wanted, but this was greatly complicated by my initial misreading the value of the UUID_STRING variable. This led to my incorrectly identifying the error as being in the sed command, when the real issue was in the variable (as you state in your answer). – fuzzydrawrings Jan 26 '22 at 00:17
2

Using GNU sed you can do as follows. Sect the lines that need commenting by manipulating the UUID_STRING variable on the left by means of bash parameter expansion and on the right by means of sed regex.

sed -Ei "
  /^UUID=${UUID_STRING#*\"}?/ s/^/#/
" /etc/fstab
guest_7
  • 5,728
  • 1
  • 7
  • 13
0

Using Raku (formerly known as Perl_6)

raku -pe 's/ ^ ("UUID=86d58af9-801b-4c25-b59d-80b52b4acc61") /\#\#\#FAULTY_DISK\#\#\#$0/;' fstab_test.txt

OR

raku -pe 's[ ^ ("UUID=86d58af9-801b-4c25-b59d-80b52b4acc61") ] = "\#\#\#FAULTY_DISK\#\#\#$0";'

Sample Input:

UUID=cb47ad8e-5b90-4ddc-97f5-2c0fa1f1b7e7 /data/sdc ext4 defaults,noatime 0 0
UUID=169da708-3c48-4306-beba-95dab722d3ab /data/sdd ext4 defaults,noatime 0 0
UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /data/sde ext4 defaults,noatime 0 0
UUID=640e2c41-d5c6-4e02-beb9-714ec99e16e2 /data/sdf ext4 defaults,noatime 0 0
UUID=58a8cddf-7ce9-431c-bb71-f4f44c8d62a5 /data/sdg ext4 defaults,noatime 0 0
UUID=6779c108-f74b-4a05-8faf-cf8752844c53 /data/sdh ext4 defaults,noatime 0 0
UUID=3c2352f6-df8e-4b14-b6c0-60caaef0dce0 /data/sdi ext4 defaults,noatime 0 0
UUID=ba59e473-d856-4c8b-a3be-4bfc40009f0d /data/sdb ext4 defaults,noatime 0 0

Sample Output:

UUID=cb47ad8e-5b90-4ddc-97f5-2c0fa1f1b7e7 /data/sdc ext4 defaults,noatime 0 0
UUID=169da708-3c48-4306-beba-95dab722d3ab /data/sdd ext4 defaults,noatime 0 0
###FAULTY_DISK###UUID=86d58af9-801b-4c25-b59d-80b52b4acc61 /data/sde ext4 defaults,noatime 0 0
UUID=640e2c41-d5c6-4e02-beb9-714ec99e16e2 /data/sdf ext4 defaults,noatime 0 0
UUID=58a8cddf-7ce9-431c-bb71-f4f44c8d62a5 /data/sdg ext4 defaults,noatime 0 0
UUID=6779c108-f74b-4a05-8faf-cf8752844c53 /data/sdh ext4 defaults,noatime 0 0
UUID=3c2352f6-df8e-4b14-b6c0-60caaef0dce0 /data/sdi ext4 defaults,noatime 0 0
UUID=ba59e473-d856-4c8b-a3be-4bfc40009f0d /data/sdb ext4 defaults,noatime 0 0

Above are answers coded in Raku, a member of the Perl-family of programming languages. Raku implements a limited number of command line flags, and the -pe (auto-printing, code-execution) flags are utilized here. Both answers use Raku's s/// substitution operator; the second example s[…] = "…" is a newer (less-backslashy) variant. Should global matches be required, insert the :global adverb at the head of the operator after the s, as in s:global/// or s:g///.

Speaking of backslashes, escaping # octothorpes is unnecessary on my particular system, but not deleterious if included. Escaped backslashes are included for users of vim, since the answers above bearing escaped octothorpes (within double-quoted strings) can be used directly on the vim command line (Ex-mode), for example:

:%! raku -pe 's[ ^ ("UUID=86d58af9-801b-4c25-b59d-80b52b4acc61") ] = "\#\#\#FAULTY_DISK\#\#\#$0";' 
jubilatious1
  • 3,195
  • 8
  • 17