Quantcast
Channel: Debian User Forums
Viewing all articles
Browse latest Browse all 2901

Programming • Re: How to list packages in Debian repositories containing firmware

$
0
0
Thank you @Aki, I'll try to explain a few things.

I use parameter expansions a lot (described in the "Parameter Expansion" section of the Bash manual) because it's much more efficient (faster) than calling an external application such as sed for example. Calling an external application in a loop may be a huge obstacle to performance. It's not that sed or grep are slow, they are very fast on their own, it's the cost of calling them repeatedly.

Code:

$> FIELD="APT-Sources: https://deb.debian.org/debian bookworm/main amd64 Packages"$> echo "$FIELD"APT-Sources: https://deb.debian.org/debian bookworm/main amd64 Packages$> sed 's/^APT-Sources: //' <<<"$FIELD"https://deb.debian.org/debian bookworm/main amd64 Packages$> echo "${FIELD#APT-Sources: }"https://deb.debian.org/debian bookworm/main amd64 Packages
We can use set -x to trace what happens

Code:

$> FIELD="APT-Sources: https://deb.debian.org/debian bookworm/main amd64 Packages"$> set -x                                                                     ### start trace$> AREA="${FIELD#APT-Sources: }"+ AREA='https://deb.debian.org/debian bookworm/main amd64 Packages'$> [[ "$AREA" == *\ * ]] && AREA="${AREA#* }" AREA="${AREA%% *}"+ [[ https://deb.debian.org/debian bookworm/main amd64 Packages == *\ * ]]    ### test if AREA contains spaces+ AREA='bookworm/main amd64 Packages'                                         ### remove characters before and up to first space in AREA+ AREA=bookworm/main                                                          ### remove characters until the last space encountered from the end$> set +x                                                                     ### return to normal execution (stop trace)+ set +x$> declare -p AREA                                                            ### display attributes (none) and value (bookworm/main) of AREA variabledeclare -- AREA="bookworm/main"
This method replaces grep and sed:

Code:

$> set -x$> time { [[ "$FIELD" != "${FIELD#APT-Sources: }" ]] && echo "${FIELD#APT-Sources: }"; }+ [[ APT-Sources: https://deb.debian.org/debian bookworm/main amd64 Packages != \h\t\t\p\s\:\/\/\d\e\b\.\d\e\b\i\a\n\.\o\r\g\/\d\e\b\i\a\n\ \b\o\o\k\w\o\r\m\/\m\a\i\n\ \a\m\d\6\4\ \P\a\c\k\a\g\e\s ]]+ echo 'https://deb.debian.org/debian bookworm/main amd64 Packages'https://deb.debian.org/debian bookworm/main amd64 Packagesreal0m0,000suser0m0,000ssys0m0,000s$> time { grep -q "^APT-Sources: " <<<"$FIELD" && echo "${FIELD#APT-Sources: }"; }+ grep -q '^APT-Sources: '+ echo 'https://deb.debian.org/debian bookworm/main amd64 Packages'https://deb.debian.org/debian bookworm/main amd64 Packagesreal0m0,003suser0m0,003ssys0m0,000s$> time { grep -q "^APT-Sources: " <<<"$FIELD" && sed 's/APT-Sources: //' <<<"$FIELD"; }+ grep -q '^APT-Sources: '+ sed 's/APT-Sources: //'https://deb.debian.org/debian bookworm/main amd64 Packagesreal0m0,005suser0m0,004ssys0m0,002s
This method also replaces sed (it sanitizes the first argument by removing characters that are not digits, lowercase ASCII letters, -, + and . in accordance with the Debian package naming policy).

Code:

$> set -- "a*b &c&&&-d+é.f@"                       ### set the first positional parameter $1$> echo "${1//[^0-9a-z\-+.]}"                      ### delete all (//) characters NOT (^) [range 0-9 or range a-z or - or + or .]abc-d+.f$> LANG="C.utf8" sed 's/[^0-9a-z+.\-]//g' <<<"$1"abc-d+.f
while <condition is true> <execute body>
read returns false on end-of-file (end of apt output)

Code:

while IFS='' read -r FIELD; do                           ### loop on apt output, keep spaces at start and end of line (IFS=''),                                                         ### keep backslashes (-r), assign value of FIELD variable    :                                                     ### bodydone < <(apt show -- "*${PTRN:-firmware}*" 2>/dev/null)  ### the value of PTRN is "firmware" if PTRN is empty. Redirect error messages to /dev/null
RESULT is an indexed array variable (-a attribute). One way to populate an array is to add values directly to it, i.e. RESULT+=( "<value>" )
apt is run in a subshell, while is run in the current environment. This is different from pipelining apt output to while in that it allows variable values ​​to be retrieved outside of while. Compare

Code:

$> declare -a RESULT$> printf '%s\n' "  aaa  bbb" "ccc ddd " | while IFS='' read -r FIELD; do RESULT+=( "$FIELD" ); done$>declare -p RESULTdeclare -a RESULT             ### while is run in a subshell, RESULT is unchanged in the current environment$> while IFS='' read -r FIELD; do RESULT+=( "$FIELD" ); done < <(printf '%s\n' "  aaa  bbb  " "ccc ddd "; TESTVAR="in_a_subshell")$> declare -p RESULTdeclare -a RESULT=([0]="  aaa  bbb  " [1]="ccc ddd ")$> declare -p TESTVARbash: declare: TESTVAR: not found
It takes more time to explain the code than to write it :)
I will be happy to answer any questions, also about the AWK programming language.
note: I suspect that the way the wc command calculates the number of words is biased because it does not interpret the code syntax.
yes, because
A word is a non-zero-length sequence of printable characters delimited by white space.
and I tend to condense AWK writing, e.g.
FNR==NR{if (/^Architecture: /){if ($2=="'"$ARCH"'" || $2=="all"){a=1} could be written
FNR == NR {if (/^Architecture: /) {if ($2 == "'"$ARCH"'" || $2 == "all") {a = 1}

Statistics: Posted by fabien — 2024-06-16 16:43



Viewing all articles
Browse latest Browse all 2901

Trending Articles