5

I have a file named myfile.csv containing the following:

 abc:123:myname:1231
 def:423324:arbitrary:value:string
 StackExchange:Unix:Linux

From the terminal I run ./myscript.sh def

The contents of myscript.sh is:

#!/bin/bash
key_word_I_am_looking_for=$1
my_variable=`cat myfile.csv | awk -F: -v keyword="$key_word_I_am_looking_for" '( $1 == keyword )' END{print "$@" }'`
echo "$my_variable"

I want the code to search for the word def or any other word in the first parameter in the myfile.csv ie abc or StackExchange. Once found I would like it to take the whole line out without the seperators and place it in the my_variable variable, and echo it out to the terminal (so the output would look like: def 423324 arbitrary value string when ./myscript.sh def is entered to the terminal. When ./myscript.sh StackExchange the output would be StackExchange Unix Linux ).

Where am I going wrong? Is there an alternative?

  • 3
    grep 'def' myfile.csv | tr ':' ' ' – Costas Apr 11 '15 at 15:36
  • 1
    while IFS=':' read -r first a b c d e ; do [ "$first" = "$key_word_I_am_looking_for" ] && echo "$first $a $b $c $d $e" ; done < myfile.csv – Costas Apr 11 '15 at 15:43
  • I like the 2nd, but instead of guessing how many fields there are, use read -a to use an array. – glenn jackman Apr 11 '15 at 15:44
  • @glennjackman Well, it is good idea. – Costas Apr 11 '15 at 15:45
9

Your awk syntax is a little wrong.

#!/bin/bash
awk -F: -v keyword="$1" '$1 == keyword {$1=$1; print}' myfile.csv

The trick here is reassigning the value of one of the fields forces awk to recalculate $0 using the output file separator. Here, the default OFS is a space, so assigning the value of $1 to itself changes the colons to spaces.

A non-awk way to write this is:

grep "^$1:" myfile.csv | tr ":" " "

but that uses regular expression matching, not string equality

  • 1
    I didn't use grep -F because we have to anchor the search at the beginning of the line. – glenn jackman Apr 12 '15 at 0:05
  • Ahh yes, my apologies. I don't read these closely enough sometimes. – mikeserv Apr 12 '15 at 0:07
  • 1
    I too often suffer from premature solve-ulation. – glenn jackman Apr 12 '15 at 0:08
3

Here is a sed alternative:

sed -n '/^def:/s/:/ /gp' myfile.csv

If you pass the string as first positional parameter:

sed -n "/^$1:/s/:/ /gp" myfile.csv
0

Through python.

$ python -c "import sys;
with open(sys.argv[2]) as f:
    for line in f:
        if sys.argv[1] == line.split(':')[0]:
            print ' '.join(line.strip().split(':'))" def file
def 423324 arbitrary value string

Just run the above script on terminal with the search keyword as firs argument and the file-name as second argument.

0

Here is a solution using grep:

grep ^abc file | awk -F ":" '{print $1" " $2" " $3" " $4}'

  • 2
    I would’ve added more anchoring to the grep, such as a trailing colon. Also, the OP asked for the result to be in a variable. – Jeff Schaller Feb 21 '18 at 11:39

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.