I have a file like
key\0value\n
akey\0value\n
key2\0value\n
I have to create a script that take as argument a word. I have to return every lines having a key exactly the same than the argument.
I tried
grep -aF "$key\x0"
but grep seems to do not understand the \x0 (\0 same result). Futhermore, I have to check that the line begins with "$key\0"
I only can use sed grep and tr and other no maching commands
Using
sed
sed
will work:The use of
\x00
to represent a hex character is a GNU extension tosed
. Since this question is taggedlinux
, that is not a problem.Since the null character does not display well, one might (or might not) want to improve the display with something like this:
Using
sed
with keys that contain special charactersIf the key itself can contain sed or shell active characters, then we must escape them first and then run
sed
against the input file:To use this script, simply supply the key as the first argument on the command line, enclosed in single-quotes, of course, to prevent shell processing.
To see how it works, let's look at the pieces in turn:
sed 's:[]\[^$.*/]:\\&:g' <<<"$1"
This puts a backslash escape in front of all sed-active characters.
printf -v script '/^%s\\x00/p' "$(sed 's:[]\[^$.*/]:\\&:g' <<<"$1")"
This creates a
sed
command using the escaped key and stores it in the shell variablescript
.sed -n "$script" file
This runs
sed
using the shell variablescript
as thesed
command.Using
awk
The question states that
awk
is not an acceptable tool. For completeness, though, here is anawk
solution:Explanation:
-F'\x00'
awk
divides the input up into records (lines) and divides the records up into fields. Here, we set the field separator to the null character. Consequently, the first field, denoted$1
, is the key.-v k=key1
This creates an
awk
variable, calledk
, and sets it to the key that we are looking for.$1 == k
This statement looks for records (lines) for which the first field matches our specified key. If a match is found, the line is printed.
To have the \0 taken into account try :
it works for me.