Find rows in a file which doesnt contain a string and add text at start of it

Viewed 190

I have data in below format in a file.

name,path:A:B
loc:D
name,for:B:C

I need to add " ," (space + comma ) at start of all those lines which doesn't have , in it in the file to get the output like below.

name,path:A:B
 ,loc:D
name,for:B:C

grep "[^,]" file .. This gives me list of lines which doesnt contain , but I am not able to add at start .

7 Answers

Could you please try following, written and tested with shown samples in GNU awk.

awk '!/,/{print OFS","$0;next} 1' Input_file

Explanation: Adding detailed explanation for above.

awk '               ##Starting awk program from here.
!/,/{               ##Checking condition if line is NOT having comma then do following.
  print OFS","$0    ##Printing OFS comma and current line here.
  next              ##next will skip all further statements from here.
}
1                   ##1 will print current line here.
' Input_file        ##Mentioning Input_file name here.

grep is not the tool here, I'd use awk or sed. Using awk:

$ awk '
BEGIN {
    FS=OFS=","  # set delimiters to ,
}
NF==1 {         # if there is only one field (consider NF<=1 for ampty records)
    $1=OFS $1   # add a delimiter in front of it
}
1' file         # output

Output:

name,path:A:B
,loc:D
name,for:B:C

Using sed:

sed -r '/\,/!s/(^.*$)/ ,\1/' file

Search for lines without a comma by using ! and then substitute the whole line for a space, comma and the existing line.

I would use GNU AWK for this task following way, let file.txt content be

name,path:A:B
loc:D
name,for:B:C

then

awk '{print /,/?$0:" ,"$0}' file.txt

output

name,path:A:B
 ,loc:D
name,for:B:C

Explanation: for every line if there is , just print that line ($0) otherwise print concatenation of space-comma (" ,") and that line ($0).

(tested in gawk 4.2.1)

You could use index to check for a comma.

awk '{print index($0, ",") ? $0 : " ," $0}' file

Output

name,path:A:B
 ,loc:D
name,for:B:C

There is lots of good answers using sed or awk here, which are perfectly fine to do that (even better than the following one). But just for fun, here is a bash only solution (without needing to invoke external programs like grep or whatever) which also do the trick:

$ while read -r; do p=""; [[ ! $REPLY =~ [^,]*\,[^,]* ]] && p=" ,"; echo "${p}${REPLY}"; done < test.txt 
name,path:A:B
 ,loc:D
name,for:B:C

The explained version:

#!/bin/bash

while read -r; do # looping over a file the right way in bash
  p="" # initializing a prefix
  [[ ! $REPLY =~ [^,]*\,[^,]* ]] && p=" ," # if the line doesn't contain a comma, the prefix will contain a comma
  echo "${p}${REPLY}"; # print the line with the prefix which can be blank or not
done < test.txt 

To edit the file itself, use ed:

printf "%s\n" "v/,/s/^/ ,/" w | ed -s file

inserts a space and comma at the start of every line that doesn't already have a comma, and then saves the modified file.

Related