babaji
babaji

Reputation: 49

How to print keys from all key-value pairs

Text file looks like this:

key11=val1|key12=val2|key13=val3
key21=val1|key22=val2|key23=val3

How can I extract keys so that:

key11|key12|key13
key21|key22|key23

I have tried unsuccessfully :

awk '{ gsub(/[^[|]=]+=/,"") }1' file.txt

gives back the actual data:

key11=val1|key12=val2|key13=val3
key21=val1|key22=val2|key23=val3

Upvotes: 2

Views: 204

Answers (5)

Claes Wikner
Claes Wikner

Reputation: 1517

awk -F'[=|]' '{print $1,$3,$5}' OFS="|" file

key11|key12|key13
key21|key22|key23

Upvotes: 1

sed

I did this with sed:

sed -r 's/([[:alnum:]]*)=[[:alnum:]]*/\1/g' < file.txt

tested here and got:

key11|key12|key13
key21|key22|key23

s/<pattern>/<subst>/ means "replace <pattern> by <subst>", and with the g in the end it will do it for every pattern found in the line.

The [[:alnum:]]* is equivalent to [0-9a-zA-Z]*, and means any number of letters or digits.

The first pattern between parentesis will correspond to \1 in the substitution, the second \2 and so on.

So, it will match every "key=value" and replace it by "key".

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 246992

Since you tagged

while IFS='=|' read -ra words; do
    n=${#words[@]}
    for ((i=1; i<n; i+=2)); do
        unset words[i]
    done
    ( IFS='|'; echo "${words[*]}" )
done < file

Upvotes: 2

shellter
shellter

Reputation: 37298

Here's one solution

echo "key11=val1|key12=val2|key13=val3" \
| awk -F'[=|]' '{
  for (i=1;i<=NF;i+=2){
    printf("%s%s", $i, (i<(NF-1))?"|":"") 
  }
  print""
}'

output

key11|key12|key13

It should also work by passing in the filename as an argument to awk, i.e.

awk -F'[=|]' '{for (i=1;i<=NF;i+=2){printf("%s%s", $i, (i<(NF-1))?"|":"") }print""}' file1 [file_more_as_will_fit]

Discussion

We use a multiple character value for FS (FieldSeperator) so each = and | char mark the beginning of a new field.

-F'[=|]'

Because we know we want to start with field1 for output and skip every other field, we use

for (i=1;i<=NF;i+=2)

printf formats the output as defined by the format string '%s%s' . There area a zillion options available for printf format strs, but you only need the value for $i (the looping value that generates the key) and whether to print a | char or not.

printf("%s%s", $i ...)

And we use awk's ternary operator, which evaluates what element number is being processed (i<..). As long as it is not the 2nd to last field, the | char is emitted.

(i<(NF-1))?"|":"" 

IHTH

Upvotes: 1

Kent
Kent

Reputation: 195159

gawk

This can be done by awk, by setting FS and OFS :

kent$  awk -F'=[^|]*' -v OFS="" '$1=$1' file
key11|key12|key13
key21|key22|key23

or safer: awk -F.... '{$1=$1}1' file

substitution (by sed for example):

kent$  sed 's/=[^|]*//g' file
key11|key12|key13
key21|key22|key23

Upvotes: 1

Related Questions