sed returns "sed: command garbled" - linux

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

Related

Sed regex match with variable endings is not matchng

I have file that in simple example looks like:
some_file_name{
something
otherthing2
otherthing3
}
How ever "some_file_name" can end with end of line, space or { so I need to match every variant. To further complicate things the some_file_name contains / so delimiter needs to be different... and in the end I need to replace "something" between the some_file_name{ and the next } so the result would be:
some_file_name{
something_replaced
otherthing2
otherthing3
}
I got as far:
sed -r "\%some_file_name\($\|[[:space:]]\|\{\)%,\%\}%{s/something/something_replaced/}" "file.txt"
( sed -r is mandatory )
My best gues the issue is somewhere here: \($\|[[:space:]]\|\{\) where I try to match the 3 possible endings ... but for life of me I can't figure it out what is missing.
sed --version
sed (GNU sed) 4.2.2
sed -r "\%some_file_name($|[[:space:]]|\{)%,\%\}%{s/something/something_replaced/}" "file.txt"
-r (and -E, which is more portable, so whenever you can, choose this one) enables extended regular expressions. So you should neither escape the grouping parenthesis, nor the vertical bar, otherwise they are treated literally by sed.
Still confused? Consider this:
$ echo '(' | sed 's/(/X/'
X
$ echo '(' | sed -E 's/(/X/'
sed: -e expression #1, char 6: Unmatched ( or \(
$ echo '(' | sed -E 's/\(/X/'
X

search a line that contain a special character using sed or awk

I wonder if there is a command in Linux that can help me to find a line that begins with "*" and contains the special character "|"
for example
* Date | Auteurs
Simply use:
grep -ne '^\*.*|' "${filename}"
Or if you want to use sed:
sed -n '/^\*.*|/{=;p}' "${filename}" | sed '{N;s/\n/:/}'
Or (gnu) awk equivalent (require to backslash the pipe):
awk '/^\*.*\|/' "${filename}"
Where:
^ : start of the line
\*: a literal *
.*: zero or more generic char (not newline)
| : a literal pipe
NB: "${filename}": i've assumed you're using the command in a script with the target file passed in a double quoted variable as "${filename}". In the shell simply use the actual name of the file (or the path to it).
UPDATE (line numbers)
Modify the above commands to obtain also the line number of the matched lines. With grep is simple as to add -n switch:
grep -ne '^\*.*|' "${filename}"
We obtain an output like this:
81806:* Date | Auteurs
To obtain exactly the same output from sed and awk we have to complicate the commands a little bit:
awk '/^\*.*\|/{print NR ":" $0}' "${filename}"
# the = print the line number, p the actual match but it's on two different lines so the second sed call
sed -n '/^\*.*|/{=;p}' "${filename}" | sed '{N;s/\n/:/}'

Linux Command to make columns separated by multiple delimeters

Want to convert the following pattern
ab
cd
de
fg as
'ab','cd','de','fg' using unix / linux command .
----Guys -------- The patern is as following
QRTC1065173134
QRTC3988977812
QRTC0889556882
QUTR1641276912
ABCD1763495154
QRTC3991601819
and this is the required pattern 'QRTC1065173134','QRTC3988977812','QRTC0889556882','QUTR1641276912','ABCD1763495154','QRTC3991601819'
I agree with the comments that it's a bit unclear but, for fun sake:
A="ab cd ef gh "
echo $A | sed -e "s/^\s*/'/; s/ \{1,\}/','/g; s/\s*$/'/g"
Since the question wasn't precise, I only worked on spaces & string boundaries. So it will work with any number of characters, separated space(s). The result is also trimmed at both ends. HTH.
From the clarification, it seems that this is what you want.
$ echo "QRTC1065173134 QRTC3988977812 QRTC0889556882 QUTR1641276912 ABCD1763495154 QRTC3991601819" | sed -E "s/ /', '/g" | sed -E "s/$/'/" | sed -E "s/^/'/"
'QRTC1065173134', 'QRTC3988977812', 'QRTC0889556882', 'QUTR1641276912', 'ABCD1763495154', 'QRTC3991601819'
Here "E" is for extended regex so that we do not need to escape the regex metacharacters.
COMMENT 1: Removing an extra whitespace is left as an exercise for you.
If I understand correctly, that you have groups (e.g. ab bc de ...) separated by spaces, where you want to include a ' at the beginning/end of everything, and replace the spaces with ',' then sed can handle this with relative ease. Below ab cd ... can be any string of characters, such as QRTC1065173134. There are several ways to piece together a matching regular expression, but the following is fairly simple:
sed -e "s/\s/','/g" -e "s/^/'/" -e "s/$/'/"
example
$ echo "ab cd de fg hi" | sed -e "s/\s/','/g" -e "s/^/'/" -e "s/$/'/"
'ab','cd','de','fg','hi'
or
$ echo "QRTC1065173134 QRTC3988977812 QRTC0889556882" | sed -e "s/\s/','/g" -e "s/^/'/" -e "s/$/'/"
'QRTC1065173134','QRTC3988977812','QRTC0889556882'

unix sed command matching a word

I am trying to match a line and use sed command to substitute it. Some thing like
aaa = 10
aaa =10
aaa=10
My sed regular expression should match all those patterns and should replace with something like bbb=5. I tried with
sed -i '/ *aaa *= */bbb=5'
But this is not properly working for all the patterns. Any help will be really appreciable.
sed -i 's/\s*aaa\s*=\s*[0-9]*/bbb=5/' input_file
cat a | sed -e '1s/aaa =10/bbb=10/' -e '2s/ aaa =10/bbb=10/' -e '3s/aaa=10/bbb=10/'
cat myfile | sed 's/\s*aaa\s*=\s*\(.*\)/bbb = \1/'
The \s character class matches both tab and space

Strings extraction from text file with sed command

I have a text file which contains some lines as the following:
ASDASD2W 3ASGDD12 SDADFDFDDFDD W11 ACC=PNO23 DFSAEFEA EAEDEWRESAD ASSDRE
AERREEW2 3122312 SDADDSADADAD W12 ACC=HH34 23SAEFEA EAEDEWRESAD ASEEWEE
A15ECCCW 3XCXXF12 SDSGTRERRECC W43 ACC=P11 XXFSAEFEA EAEDEWRESAD ASWWWW
ASDASD2W 3122312 SDAFFFDEEEEE SD3 ACC=PNI22 ABCEFEA EAEDEWRESAD ASWEDSSAD
...
I have to extract the substring between the '=' character and the following blank space for each line , i.e.
PNO23
HH34
P11
PNI22
I've been using the sed command but cannot figure out how to ignore all characters following the blank space.
Any help?
Use the right tool for the job.
$ awk -F '[= ]+' '{ print $6 }' input.txt
PNO23
HH34
P11
PNI22
Sorry, but have to add another one because I feel the existing answers are just to complicated
sed 's/.*=//; s/ .*//;' inputfile
This might work for you:
sed -n 's/.*=\([^ ]*\).*/\1/p' file
or, if you prefer:
sed 's/.*=\([^ ]*\).*/\1/p;d' file
Put the string you want to capture in a backreference:
sed 's/.*=\([^ =]*\) .*/\1/'
or do the substitution piecemeal;
sed -e 's/.*=//' -e 's/ .*//'
sed 's/[^=]*=\([^ ]*\) .*/\1/' inputfile
Match all the non-equal-sign characters and an equal sign. Capture a sequence of non-space characters. Match a space and the rest of the line. Substitute the captured string.
A chain of grep can do the trick.
grep -o '[=][a-zA-Z0-9]*' file | grep -o '[a-zA-Z0-9]*'

Resources