Matching Third Field in a CSV with Pattern File in Gnu Linux (Awk/Sed/Grep)

Is it possible replace the value of a cell in a csv file using grep,sed or both

Assuming your CSV file is as simple as what you show (no commas in quoted fields), and your newvalue does not contain characters that sed would interpret in a special way (e.g. ampersands, slashes or backslashes), the following should work with just sed (tested with GNU sed):

sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv

Demo:

$ cat file.csv
Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890
$ rownum=3
$ col=2
$ newvalue="NEW"
$ sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW,4567
3,XYZ,7890

Explanations: $rownum is used as the address (here the line number) where to apply the following command. s is the sed substitute command. [^,]* is the regular expression to search for and replace: the longest possible string not containing a comma. $newvalue is the replacement string. $col is the occurrence to replace.

If newvalue may contain ampersands, slashes or backslashes we must sanitize it first:

sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv

Demo:

$ newvalue='NEW&\/&NEW'
$ sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
$ echo "$sanitizednewvalue"
NEW\&\\\/\&NEW
$ sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW&\/&NEW,4567
3,XYZ,7890

using grep (or awk) to extract two consecutive words

You may use this awk that loops through all the fields and matches a field using regular expression ^P[LR]:Z: and appends it into a variable to print it in the end.

awk -v OFS='\t' '
{
s = ""
for (i=1; i<=NF; ++i)
if ($i ~ /^P[LR]:Z:/)
s = (s ? s OFS : "") $i
print s
}' file

PL:Z:SL3.0ch01_5122724_5122846_FW PR:Z:None
PL:Z:SL3.0ch05_3501697_3501846_FW PR:Z:None
PL:Z:SL3.0ch02_39003135_39003329_FW PR:Z:None

How to use awk to print lines where a field matches a specific string?

In awk:

awk '$2 == "LINUX" { print $0 }' test.txt

See awk by Example for a good intro to awk.

In sed:

sed -n -e '/^[0-9][0-9]* LINUX/p' test.txt

See sed by Example for a good intro to sed.

Awk pattern matching on output not input

Assuming that field 7 contains the URL you're interested in, use

awk '$7 ~ /\.html/ {print <your-field-list>}'

I think the right field number depends on the format of your log file. I could be wrong.

That tells awk to print your field list only if the seventh field matches a literal dot followed by "html".

awk: csv split works, but ignores the last field in the row

This awk will do what you're looking for:

awk -F ',' -v tId="$1" '$0 ~ "(^|,)" tId "(,|$)"' file

Alternatively this egrep will also do the job:

egrep '(^|,)306(,|$)' file

UPDATE: Based on your comments below you can use:

awk -v tId="$1" 'BEGIN{FS=OFS=","} {p=$0; $1=$2=""} $0 ~ "(^|,)" tId "(,|$)"{print p}' file


Related Topics



Leave a reply



Submit