user1155413
user1155413

Reputation: 169

shell loop match a regex in the current line

I'm trying to create a script to fix a csv file like this:

field_one,field_two,field_three
,field_two,field_three

So I need to check inside my loop if the current line is missing field_one and replace it with sed with a new value for field_one (overwrite the line missing field_one).

For this i have a loop but i need some help with identifying if the line is missing field one or not. I should probably use grep? but how to use it in a loop and get its response?

while read -r line; do  
    # this is pseudocode:
    # if $line matches regex then
         #  sed 's/,/newfieldone/'
         #  overwrite the corrected line in the file
    # end if
done < my_file

Thanks a lot in advance for your help!!!!

Upvotes: 0

Views: 1285

Answers (11)

ant
ant

Reputation: 1

What about the use of bash only

while IFS=\, read field_one field_two rest_of_line
  echo "${field_one:-default_field_one_value},$field_two,$rest_of_line"
doen < my_file > my_corecct_file

where the 'default_field_one_value' is used if the 'field_one' is empty

Upvotes: 0

jaypal singh
jaypal singh

Reputation: 77135

. . . and another awk one-liner:

awk '$1==""{$1="field_one"}1' FS=',' OFS=',' file

Upvotes: 1

SiegeX
SiegeX

Reputation: 140417

This is a pretty short 1-liner with awk

awk '{$1="field_one"}1' FS=',' OFS=',' file.csv

Upvotes: 1

Zsolt Botykai
Zsolt Botykai

Reputation: 51653

sed -i 's/^,/fieldone,/' YOURFILE

Will replace every line starting , with fieldone, (inplace, so the original file gets overwritten, if you need a backup, try -i.backup).

If you want a dynamic fieldone value, well it depends, how dynamic want it to be :-), e.g.:

MYDYNAMICFIELDONE="DYNAF1"
sed -i "s/^,/${MYDYNAMICFIELDONE},/" YOURFILE

Or with your while loop:

while read -r line; do  
    MYDYNAMICFIELDONE="SET IT"
    sed -i "s/^,/${MYDYNAMICFIELDONE},/"
done < my_file > tmpfile
mv tmpfile my_file

Or with awk:

awk '{
       /^,/ { 
               DYNAF1="SET IT HERE"
               print gensub("^,",DYNAF1 ",","g",$0)
            }
      } INPUT > OUTPUT

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 247022

Simple bash solution using case statemetn:

while read -r line; do  
  case "$line" in
    ,*) printf "%s%s\n" newfieldone "$line" ;;
    *)  printf "%s\n" "$line" ;;
  esac
done < my_file

case uses "glob" matching, not regular expressions, so ,* matches a string beginning with a comma.

Upvotes: 1

potong
potong

Reputation: 58473

This might work for you:

a=Field_one,Field_two,Field_three
sed '/^,/c\'$a'' file
field_one,field_two,field_three
Field_one,Field_two,Field_three

Or if just inserting field_one:

a=Field_one
sed '/^,/s/^/'$a'/' file
field_one,field_two,field_three
Field_one,field_two,field_three

Upvotes: 1

Ortwin Angermeier
Ortwin Angermeier

Reputation: 6193

with sed try something like that:

sed -i 's|\(^,.*\)|new_field_one\1|g' <your file>

Upvotes: 1

bob
bob

Reputation: 390

Just for the heck of it, here's a solution in awk:

awk '{FS=","} {if ($1 == "") print "field_one" $0;else print $0} ' < /tmp/test.txt

Upvotes: 2

anubhava
anubhava

Reputation: 785551

Inside your loop you can run following sed command:

sed 's/^\s*,/newfieldone,/'

Upvotes: 3

dogbane
dogbane

Reputation: 274738

To see if a line begins with a , and is hence missing field one, you can use if [[ "$line" =~ ^, ]].

For example:

while read -r line; do  
  if [[ "$line" =~ ^, ]]
  then
    echo "newfieldone$line"
  else
    echo "$line"
  fi
done < my_file

Upvotes: 2

user647772
user647772

Reputation:

$ sed -e "/^,/s/^,\([^,]*\),\([^,]\)/new_field_one,\1,\2/" < my_file

Edit: This probably is too complicated. Take one of the other fine answers :)

Upvotes: 1

Related Questions