I have a script that I do not quite understand yet. The script assigns a configuration file to a hardware.

I do not quite understand the following two lines:

export TYPE=$(dmidecode -s system-product-name | sed 's/^[ \t]*//;s/[ \t]*$//')

CONFIG_FILE=$(find . -type f -name *.cfg -exec grep -l -i "$TYPE" '{}' \; | sed 's|./||')

Both assign the result of a query to a variable. The first picks up the product name and replaces characters (which one?). The second looks for a configuration file using the result from the first query. But what exactly is the search string and what is being replaced here using sed.

Some more info: There are already some configurations files. If the dmidecode command finds a "HP EliteBook 850 G5" the next step says it would use the "WIN10_HP_ELITE_8x_G5.cfg" file. Now i have to make a file for a "HP ProBook x360 440 G1" and want to understate how this works.

  • 4
    Have you added some extra spaces in the shown examples? E.g. in the sed expression? – laenkeio May 10 at 6:54
  • Sorry, there where som additional spaces in the commands. I added some more infos. – Jan May 10 at 9:06
  • The CONFIG_FILE=... command will put in the CONFIG_FILE variable the list of names of files which contain the string held by the TYPE variable and are located in the current directory (.) and its subdirectories. File names are only required to end in .cfg—except, the command as is will fail with an error if the current directory has more than one file whose name ends in .cfg unless an option that prevents the shell from globbing was set (e.g. set -f in Bash). It should probably be '*.cfg' (with quotes). – fra-san May 12 at 12:26
sed 's/^[ \t]*//'

The anchor ^ tells sed to start at the beginning of the line and the regex group [ \t]* to match all * spaces [ ] or tabs [\t] from the start of the line until the first non-match and replace them with nothing // (i.e. to delete them).

Within the square brackets [] you may specify a range of characters to match.

sed 's/[ \t]*$//'

The anchor $ marks the end of a line, so this time sed matches all spaces and tabs back from the end of the line to the first non-match and, again replaces them with nothing.

Your second expression searches for all `.cfg' files below the current directory

find . -type f -name *.cfg

and grep them individually

-exec grep -li "$TYPE" '{}' \; 

looking for a cased insensitive match -i for whatever string is stored in the $TYPE variable and returns the filename -l for any matches. It is impossible to tell from your post what $TYPE contains

The final sed uses a different separator (sed takes the first non-command character in your argument as a separator, so you can use anything that suits you and in this case you don't want the usual / because it is one of your search characters and sed 's/.\///' is less clear)

sed 's|./||' 

will remove the first two characters from each of the grep filenames whenever the second character is a /. This is because the first . is a wildcard match for 'any character'.

This is probably meant to remove the ./ from all of the pathnames (and it will in this case) but the . is interpreted as 'any character' rather than a literal .. To ensure only a literal . is replaced then the special character . should be escaped

sed 's|\./||'

And the grep matches are finally bundled as a space separated list into

  • Thank you for the detailed explaination. I will test something and then i can say if i get it or not. – Jan May 10 at 12:53
  • Minor points: 1) It may be worth pointing out that sed 's/^[ \t]//' will only match <tab>s if it supports an extension to POSIX (as GNU sed does); POSIX mandates \ to have no special meaning in bracket expressions. 2) <newline>s in the list populating CONFIG_FILE will be preserved, thus it won't be exactly "space separated". (Sorry for re-posting, I didn't notice my previous comment wasn't properly formatted). – fra-san May 12 at 14:29
sed 's/^[\t]*//; s/[\t]*$//'

This will replace all tabs before and after line breaks with nothing.

The second sed operation has at time of this writing a syntax error and won't work at all.

  • Remove the square brackets from around the \t as that introduces a subtle shift in it's interpretation. Rather it takes it to mean to remove leading and trailing instances of backslash or alphabet t. Not what it appears at first glance. – Rakesh Sharma May 10 at 9:24
  • https://linux.die.net/man/8/dmidecode
  • regarding the sed part of the first line : there are many extra spaces (added when posting code here ?). Anyway, what this part does is remove TAB characters found at the beginning or at the end of lines output by dmidecode. The result ends in the TYPE variable
  • the second line (extra spaces again) is pretty mysterious as we don't have enough information :

    • no information about the $HW_TYPE variable
    • the sed part looks incomplete to me (are you sure this 2nd line actually works ?)
  • It does not remove all tabs, only those preceeding or following a line break. – Panki May 10 at 7:04
  • @Panki : correct. Just edited my answer. Thx – Httqm May 10 at 7:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.