"
hongy...@gmail.com" <
hongy...@gmail.com>:
>On Thursday, April 15, 2021 at 6:44:47 AM UTC+8, Helmut Waitzmann wrote:
>> {
>> printf '%s\n' 'ibase=16' &&
>> printf '%s\n' b0 36 1b 76 |
>> LC_ALL=POSIX tr -- '[:lower:]' '[:upper:]'
>> } | bc |
>> xargs -E '' -- printf \''\\%.4o'\''\n' |
>
>I find the following description from the pertinent man pages:
>
>$ man xargs
> -E eof-str
> Set the end of file string to eof-str.
>
I guess that your 'xargs' is GNU 'xargs'. If that's the case,
note the following paragraph in its manual page:
SEE ALSO
find(1), locate(1), locatedb(5), updatedb(1),
fork(2), execvp(3), kill(1), signal(7),
The full documentation for xargs is maintained as a
Texinfo manual. If the info and xargs programs are
properly installed at your site, the command info
xargs should give you access to the complete manual.
Therefore the 'info' manual is the definitive reference for GNU
'xargs' (the 'man' documentation of 'xargs' is wrong here):
'-E EOF-STR'
'--eof[=EOF-STR]'
'-e[EOF-STR]'
Set the logical end of file marker string to EOF-STR. If
the logical end of file marker string occurs as a line of
input, the rest of the input is ignored. If EOF-STR is
omitted ('-e') or blank (either '-e' or '-E'), there is no
logical end of file marker string. The '-e' form of this
option is deprecated in favour of the POSIX-compliant '-E'
option, which you should use instead. As of GNU 'xargs'
version 4.2.9, the default behaviour of 'xargs' is not to
have a logical end of file marker string. The POSIX
standard (IEEE Std 1003.1, 2004 Edition) allows this.
=>
xargs -E ''
won't ignore any input but read until the end of the data
has been reached. GNU 'xargs' will behave the same without
that option, too. But in general, POSIX 'xargs' might behave
different without it.
Because that is my intention, that 'xargs' should not ignore any
input, I'll supply that option.
>$ man 3 printf
> o, u, x, X
> The unsigned int argument is converted to unsigned octal (o),
>
>But, I still can't figure out the purpose of the above command.
>
For example:
printf \''\\%.4o'\''\n' 4 8 9 16 64 128 255
will output the following lines:
'\0004'
'\0010'
'\0011'
'\0020'
'\0100'
'\0200'
'\0377'
>> xargs -E '' -- printf '%b' |
'xargs' will read the octal numbers, remove the apostrophes and
invoke printf, supplying the backslash‐prepended 4‐digit octal
numbers as addtional parameters.
>
>I find the following explanation:
>
>$ man 1 printf
>%b ARGUMENT as a string with '\' escapes interpreted, except
>that octal escapes are of the form \0 or \0NNN
>
>But I still can't figure out how it works with the previous command.
>
Let me give an example: The shell command line
printf '%b' '\0110' '\0145' '\0154' '\0154' '\0157' \
'\0054' '\0040' '\0167' '\0157' '\0162' '\0154' \
'\0144' '\0041' '\0012'
will output the line
Hello, world!
>> od -v -A n -t x4
>$ man 1 od
> -A, --address-radix=RADIX
> output format for file offsets; RADIX is one of
> [doxn], for Decimal, Octal, Hex or None
>
> -v, --output-duplicates
> do not use * to mark line suppression
>
> -t, --format=TYPE
> select output format or formats
>
> x[SIZE]
> hexadecimal, SIZE bytes per integer
>
>So, the above command means the following:
>
>Use 4 bytes per integer format as the output, don't suppress
>duplicate lines, and without address-radix.
>
You didn't construct the 'od' command you posted in the OP by
yourself but only crasped it out of the WWW? So the WWW gave
bad advice to you, because it didn't supply the '-v' option and
supplied '-t' 'x4' rather than '-t' 'x1', causing the
little‐endian‐big‐endian trouble.
>
>> yields the output '761b36b0'. If that's the case, you could have
>> done
>>
>> {
>> printf '%s\n' 'ibase=16' &&
>> printf '%s\n' b0 36 1b 76 |
>> LC_ALL=POSIX tr -- '[:lower:]' '[:upper:]'
>> } | bc | xargs -E '' -- printf \''\\%.4o'\''\n' |
>> xargs -E '' -- printf '%b' |
>> dd of=disk.img bs=1 seek=440 conv=notrunc
>>
>> to restore the original partuuid.
>>
>>
>> Read the documentation ('info', 'man') of the commands 'printf',
>> 'tr', 'bc', 'xargs', 'od', and 'dd', to learn, what they are doing
>> in the commands above.
Let me comment on the multi‐line shell command above:
# Print the sedecimal numbers, one per line, converted to
# decimal:
{
# Print 'ibase=16':
#
printf '%s\n' 'ibase=16' &&
# Print the sedecimal numbers, one per line:
#
printf '%s\n' b0 36 1b 76 |
# Feed the sedecimal numbers to 'tr' in order to convert
# all letters to upper case (because 'bc' doesn't accept
# lower case sedecimal numbers):
#
LC_ALL=POSIX tr -- '[:lower:]' '[:upper:]'
} |
# Let bc convert the upper case sedecimal numbers to decimal
# numbers and print them one per line:
#
bc |
# Let 'xargs' read the decimal numbers and invoke 'printf',
# supplying the decimal numbers as additional parameters:
#
# 'printf' will convert each of the decimal numbers to a
# 4-digit octal number and prepend an apostrophe and a
# backslash before it and append an apostrophe after it,
# then output it, one line per number:
#
# printf \''\\%.4o'\''\n' the decimal numbers...
#
xargs -E '' -- printf \''\\%.4o'\''\n' |
# Let 'xargs' read each backslash-prepended
# apostrophe-surrounded 4-digit octal number and invoke
# 'printf', supplying the backslash-prepended 4-digit octal
# numbers as additional prameters:
#
# printf '%b' '\nnnn' '\nnnn' ...
#
# 'printf' will convert each octal value to a byte using
# that octal number as the code, i.e. convert the octal
# numbers to their raw form, which is essentially the
# inverse of
#
# od -A n -t o1
#
xargs -E '' -- printf '%b' |
#
# In summary: Output the raw values of the sedecimal coded
# bytes. These can be fed to 'dd'.