I trying to use sed to remove the linefeed from lines that contain a pattern.
My lines are:
Format: 0000000
InputMask: &&&&&&&
OrdinalPosition: 0
Required: True
SourceField: LOAN-NO
SourceTable: MASTER
I want it to look like this:
Format: 0000000
InputMask: &&&&&&&
OrdinalPosition: 0
Required: True
SourceField: LOAN-NO:SourceTable: MASTER
My code is:
cat file.txt | sed 's/\(*.SourceField.*\)\(\n\)/\1:/g'
The code doesn't change anything.
In fact even when I remove the pattern and look for \n it still doesn't work
This seems to work for all lines:
cat file.txt | sed ':a;N;$!ba;s/\n//g'
but I cant get it to work for just the lines containing with SourceField.
I'd like to understand why the first line doesn't work, and how the second line can be adapted to work with just the lines containing the pattern.
Any help would be appreciated.
Thanks!
$ sed -E '/SourceField:/{N;s/\n */:/;}' file
Format: 0000000
InputMask: &&&&&&&
OrdinalPosition: 0
Required: True
SourceField: LOAN-NO:SourceTable: MASTER
your first script won't work because sed operations are line based. In the pattern space you can remove the new line.
Using perl in multiline context (kind of natural):
perl -0 -pe 's/(\s+SourceField:\s+LOAN-NO)\n\s+/$1:/' file
the \s+ are spaces (or blanks). Isn't a clear and readable code ?
the -0 makes Perl to slurp the whole file in a single string variable
Format: 0000000
InputMask: &&&&&&&
OrdinalPosition: 0
Required: True
SourceField: LOAN-NO:SourceTable: MASTER
Related
I want to get the first line of a file that is not commented out with an hash, then append a line of text just after that line just before that line.
I managed to get the number of the line:
sed -n '/^\s*#/!{=;q}' file // prints 2
and also to insert text (specifying the line manually):
sed '2 a extralinecontent' file
I can't get them working together as a one liner or in a batch.
I tried command substitution (with $(command) and also with backticks) but I get an error from bash:
sed '$(sed -n '/^\s*#/!{=;q}' file) a extralinecontent' file
-bash: !{=: event not found
and also tried many other combinations, but no luck.
I'm using gnu-sed (via brew) on macOS.
This might work for you (GNU sed):
sed -e '/^\s*#/b;a extra line content' -e ':a;n;ba' file
Bail out of any lines beginning with a comment at the beginning of the file, append an extra line following the first line that is not a comment and keep fetching/printing all the remaining lines of the file.
Here's a way to do it with GNU sed without reading the file twice
$ cat ip.txt
#comment
foo baz good
123 456 7889
$ sed -e '0,/^\s*[^#[:space:]]/ {// a XYZ' -e '}' ip.txt
#comment
foo baz good
XYZ
123 456 7889
GNU sed allows first address to be 0 if the other address is regex, that way this will work even if first line matches the condition
/^\s*[^#[:space:]]/ as sed doesn't support possessive quantifier, need to ensure that the first character being matched by the character class isn't either a # or a whitespace character
// is a handy shortcut to repeat the last regex
a XYZ your required line to be appended (note that your question mentiones insert, so if you want that, use i instead of a)
I am trying to grep the line from file and then from $1 I am trying to change the character.
eg
cat file1.txt
Surjit
Shilpa
cchiku
end of file
I tried and grepped the line which start with s.
grep -e "S"
Then I want to replace the 4th character to x for all grepped result in the file1.txt
I tried
sed -i "s/./x/4" file1.txt
How can I do this only for grepped results?
You can use the sed '/pattern/s/find/replace/' file syntax:
sed '/^S/s/./x/4' file
# ^^ ^^^^^^^
# | replace the 4th character with x
# |
# on lines starting with S
With your file:
$ sed '/^S/s/./x/4' file
Surxit
Shixpa
cchiku
end of file
Note I am using /^S/ as a pattern to match lines starting with S, because if you just say /S/ it will match any line containing S. The anchor ^ indicates the beginning of the line.
An alternative to fedorqui's answer is to include the starting with S condition into the pattern itself:
sed 's/^\(S..\)./\1x/' file
The command matches lines starting with S and puts the S and the following two characters into a matching group. In the replacement part the content of the matching group will get reused and next character after it will get replaced by x.
awk -v FS="" -v OFS="" '/^S/{$4="x"}1' infile
Surxit
Shixpa
cchiku
end of file
For example, my file has the following data:
$ cat sample.txt
19999119999,string1,dddddd
18888135790,string2,dddddd
15555555500,string3,dddddd
This is a sample data. How can we remove ONLY first digit from each row? My output should be:
$ cat output.txt
9999119999,string1,dddddd
8888135790,string2,dddddd
5555555500,string3,dddddd
Is there any way to parse each line character wise using grep or sed?
Or any other way to get the desired output?
You just need to print from the second character on:
$ cut -c2- file
9999119999,string1,dddddd
8888135790,string2,dddddd
5555555500,string3,dddddd
Or, using sed, remove the first char:
$ sed 's/^.//' file
9999119999,string1,dddddd
8888135790,string2,dddddd
5555555500,string3,dddddd
Try this:
$ sed -r 's/^[0-9](.*)/\1/' sample.txt
Output:
9999119999,string1,dddddd
8888135790,string2,dddddd
5555555500,string3,dddddd
^[0-9] - The first digit of each line
(.*) - The content of each line except the first digit
\1 - Denote the content of (.*)
Sorry for my bad English.
Grep can solve this with a look behind. For that you need -P option :
grep -Po '(?<=^\d)(.+)' file
or in shorthand :
grep -Po '^\d\K.+' file
The (?<=^\d)/^\d\K part is the look behind that matches the first digit.
I know how to remove all trailing spaces from a file, e.g :
sed -i 's/ *$//' file
Is there a way to do it, but not in lines containing only spaces?
Something in the spirit of :
sed -i 's/[a-zA-Z0-9;}{] *$/[a-zA-Z0-9;}{]/' file
^ keep the original characters
Preferably, but not necessariliy, with sed.
Any linux supported solution will do.
Thanks
Just make sure some other character appears before:
sed -r 's/([^\s])\s+$/\1/' file
This checks if a non-space character (\s) appears followed by any amount of spaces. If so, just print this non-space character back, so that the trailing spaces are removed.
Test
Using cat -vet to see the markers:
$ cat -vet a
hello $
$
bye $
$ sed -r 's/([^\s])\s+$/\1/' a | cat -vet -
hello$
$
bye$
I have a file in which some lines start by a >
For these lines, and only these ones, I want to keep the first eleven characters.
How can I do that using sed ?
Or maybe something else is better ?
Thanks !
Muriel
Let's start with this test file:
$ cat file
line one with something or other
>1234567890abc
other line in file
To keep only the first 11 characters of lines starting with > while keeping all other lines:
$ sed -r '/^>/ s/(.{11}).*/\1/' file
line one with something or other
>1234567890
other line in file
To keep only the first eleven characters of lines starting with > and deleting all other lines:
$ sed -rn '/^>/ s/(.{11}).*/\1/p' file
>1234567890
The above was tested with GNU sed. For BSD sed, replace the -r option with -E.
Explanation:
/^>/ is a condition. It means that the command which follows only applies to lines that start with >
s/(.{11}).*/\1/ is a substitution command. It replaces the whole line with just the first eleven characters.
-r turns on extended regular expression format, eliminating the need for some escape characters.
-n turns off automatic printing. With -n in effect, lines are only printed if we explicitly ask them to be printed. In the second case above, that is done by adding a p after the substitute command.
Other forms:
$ sed -r 's/(>.{10}).*/\1/' file
line one with something or other
>1234567890
other line in file
And:
$ sed -rn 's/(>.{10}).*/\1/p' file
>1234567890