to read a file in UNIX and manipulate - unix

I have one requirement that i have to read the file and manipulate. I have to replace the single double quote into double double quote if it is found in any fields. fields are separated by |.
Please find below for better understanding.
Input:
1234567|9393874|"Hi"|"How are "you""
98647489|20370483|"i am "good""|"what about "you""
output :
1234567|9393874|"Hi"|"How are ""you"""
98647489|20370483|"i am ""good"""|"what about ""you"""

I would replace all the "edge" quotes with another character and then replace the "inner" ones:
sed -e 's/|"/|_/g' -e 's/"|/_|/g' -e 's/"$/_/' file | sed 's/"/""/g' | sed 's/_/"/g'
It returns:
1234567|9393874|"Hi"|"How are ""you"""
98647489|20370483|"i am ""good"""|"what about ""you"""
Step by step:
$ sed -e 's/|"/|_/g' -e 's/"|/_|/g' -e 's/"$/_/' a
1234567|9393874|_Hi_|_How are "you"_
98647489|20370483|_i am "good"_|_what about "you"_
$ sed -e 's/|"/|_/g' -e 's/"|/_|/g' -e 's/"$/_/' a | sed 's/"/""/g'
1234567|9393874|_Hi_|_How are ""you""_
98647489|20370483|_i am ""good""_|_what about ""you""_
$ sed -e 's/|"/|_/g' -e 's/"|/_|/g' -e 's/"$/_/' a | sed 's/"/""/g' | sed 's/_/"/g'
1234567|9393874|"Hi"|"How are ""you"""
98647489|20370483|"i am ""good"""|"what about ""you"""

Related

Ignore specific patterns in line using sed

I'm trying to grep the word which starts with group keyword & ends with -wx in the given line. Also I need to ignore the below words.
Starts with default:group and ends with -wx
group::-wx
My Findings
echo "# file: /test/test123 # owner: own # group: acct user::r-- group::r-x mask::rwx other::r-x default:user::r-- default:user:an:--x default:group::r-x default:group:fin:-wx default:mask::rwx default:other::r-x" | grep -o "group:[^ ]*-wx" | sed '/group::-wx/d';'/default:[^ ]*:[^ ]*-wx/d'
Actual result
fin:-wx
Expected result
<null>
You already have a grep to select what you want, simply add grep statements to remove those you do not want.
Like so:
LINE="# file: /test/test123 # owner: own # group: acct user::r-- group::r-x mask::rwx other::r-x default:user::r-- default:user:an:--x default:group::r-x default:group:fin:-wx default:mask::rwx default:other::r-x"
echo $LINE | grep -o "group:[^ ]*-wx" \
| grep -vo "default:group:[^ ]*-wx" \
| grep -vo "group::-wx"
On my linux it returns nothing, which is what you expected. I do not have other test samples, but I think this is ok.
As you are first extracting the substring group:fin:-wx out of
default:group:fin:-wx with grep, the following sed filter
/default:[^ ]*:[^ ]*-wx/d no longer works.
A workaround is to change the order of filtering:
str="# file: /test/test123 # owner: own # group: acct user::r-- group::r-x mask::rwx other::r-x default:user::r-- default:user:an:--x default:group::r-x default:group:fin:-wx default:mask::rwx default:other::r-x"
echo "$str" | sed -e 's/default:group:[^ ]*-wx//' -e 's/group::-wx//' | grep -o 'group:[^ ]*-wx'
As an alternative, if your grep supports -P option, you can make use of positive lookbehind as:
echo "$str" | grep -Po '(?<= )group:[^ ]*-wx' | sed -e '/group::-wx/d' -e '/default:[^ ]*:[^ ]*-wx/d'
The pattern (?<= ) forces the pattern match preceded by a whitespace without
including it in the output.

Sed command garbled on Solaris [duplicate]

I have this data in file.txt:
1234-abca-dgdsf-kds-2;abc dfsfds 2
123-abcdegfs-sdsd;dsfdsf dfd f
12523-cvjbsvndv-dvd-dvdv;dsfdsfpage
I want to replace the string after "-" and up to ";" with just ";", so that I get:
1234;abc dfsfds 2
123;dsfdsf dfd f
12523;dsfdsfpage
I tried with the command:
sed -e "s/-.*;/;" file.txt
But it gives me the following error:
sed command garbled
Why is this happening?
sed replacement commands are defined as (source):
's/REGEXP/REPLACEMENT/[FLAGS]'
(substitute) Match the regular-expression against the content of the pattern space. If found, replace matched string with REPLACEMENT.
However, you are saying:
sed "s/-.*;/;"
That is:
sed "s/REGEXP/REPLACEMENT"
And hence missing a "/" at the end of the expression. Just add it to have:
sed "s/-.*;/;/"
# ^
You are missing a slash at the end of the sed command:
Should be "s/-.*;/;/"
-.* here the * greedy, so this would fail if there are more than one ;
echo "12523-cvjbsvndv-dvd-dvdv;dsfdsfpage;test" | sed -e "s/-.*;/;/"
12523;test
Change to -[^;]*
echo "12523-cvjbsvndv-dvd-dvdv;dsfdsfpage;test" | sed -e "s/-[^;]*;/;/"
12523;dsfdsfpage;test
This should work :
sed 's/-.*;/;/g' file > newFile

Using sed to enclose matches in double quotes

I'm trying to extract headers from emails and create a JSON fragment from them. I'm using sed to pull out the keys and values, but it's failing to put the trailing quote on each of the lines:
$ cat email1 | grep -i -e "^subject:" -e "^from:" -e "^to:" | \
sed -n 's/\^([^:]*\):[ ]*\(.*\)$/"\1":"\2"/gp'
"From":"Blah Blech <blah.blech#blahblech.com>
"To":"foo#bar.com
"Subject":"Yeah
I don't understand why the replacement pattern isn't working.
awk to the rescue!
$ awk -F": *" -vOFS=":" -vq="\"" 'tolower($0)~/^from|to|subject/
{print q$1q,q$2q}' email1
which combines cat or grep steps as well.
Stripping the carriage returns as #tripleee suggested fixed the issue with sed (using ctrl-v ctrl-m to capture the literal carriage return):
$ cat email1 | tr -d '^M' | grep -i -e "^subject:" -e "^from:" -e "^to:" | \
sed -n 's/^\([^:]*\):[ ]*\(.*\)$/"\1":"\2"/gp'
"From":"Blah Blech <blah.blech#blahblech.com>"
"To":"foo#bar.com"
"Subject":"Yeah"

Need data after Last comma in field1 from the Text in Unix

Need you help on the below query.
$cat sample.txt
414d51204d5150525447575648415050529a6af298e,,,002330618820140707134048 ,+0657,45675
414d51204d514e55533732355051543051696344201645c6,002330618820140707134048 ,+0657,tgre,ghty
Need all fields after last comma "," in field 1.As you can see there are lots of (414d51204d5150525447575648415050529a6af298e,,,)
The output has to be like as below.
Expected Output:
002330618820140707134048 ,+0657,45675
002330618820140707134048 ,+0657,tgre,ghty
Thanks
In case the others do not work here is a perl oneliner:
perl -lne 'print $1 if /.*?,+(.*)/'
Output:
002330618820140707134048 ,+0657,45675
002330618820140707134048 ,+0657,tgre,ghty
You can use the shell program .
cat sample.txt | sed -n 1'p' | tr ',' '\n' | while read word; do
echo $word
done
You can use sed and cut :
sed to remove empty fields
cut to select the required fields
Example:
sed -r 's/,+/,/g' < text.txt | cut -d',' -f2-
Output:
002330618820140707134048 ,+0657,45675
002330618820140707134048 ,+0657,tgre,ghty
Using egrep or grep -E:
egrep -o '[0-9]{24}\s+\S+' your_file
Using normal grep:
grep -o '[0-9]\{24\}[[:blank:]]\+[^[:blank:]]\+' your_file
Output:
002330618820140707134048 ,+0657,45675
002330618820140707134048 ,+0657,tgre,ghty
Or using sed:
sed -e 's/^[^[:blank:]]\+,//' your_file
Or
sed -e 's/^[^ \t]\+,//' your_file
Or just about space:
sed -e 's/^[^ ]\+,//' your_file

Match specific lines in sed command

How can I match a set of specific lines for a substitution command?
(incorrect):
sed -e'71,116,211s/[ ]+$//' ...
I want to strip trailing whitespace on lines 71, 116 and 211 only
You could try something like:
awk 'NR== 71 || NR == 116 || NR == 211 {sub(/ *$/,"",$0)}{print $0}'
or
sed '71s/ *$//;116s///;211s///'
sed '71bl;116bl;211bl;b;:l;s/[ ][ ]*$//' input
For any specified line, this script jumps to the label l. Other lines will jump to the end of the script with the bare branch.
And an awk solution:
awk -v k="71,116,221" 'BEGIN{split(k,a,",")}
(NR in a) { sub(/ *$/,"",$0) }1' input
This might work for you (GNU sed):
sed -r '/\s+$/!b;71s///;116s///;221s///' file
or perhaps:
sed -e '/ *$/!b' -e '71s///' -e '116s///' -e '221s///' file
or as has been said already:
sed -e '71ba' -e '116ba' -e '221ba' -e 'b' -e ':a' -e 's/ *$//' file

Resources