Delete everything except first line - bbedit

This should be simple, but I'm stumped.
I'm starting with:
Line 1
Line 2
Line 3
Line n
And I want to end up with:
Line 1
I'm using BBEdit, doing a search and replace with grep -- replacing with nothing.

This seems to work:
\r([^<]*)

Related

Delete a paragraph from a file using sed

I have a markdown file that looks something like this:
markdown.md
# Title1
line 1
line 2
line 3
# Title2
line 1
line 2
line 3
I'd like to be able to delete one of the paragraphs by searching for the title. I would need to delete the title, the following line, and then every subsequent line that is not blank.
The desired output would be:
# Title2
line 1
line 2
line 3
I was doing some reading about using {} to group multiple commands together but I can't seem to quite get the syntax right.
cat markdown.md | sed '/^# Title1.*/,+1d {/^\s*$/d}'
My thinking was this would delete the line beginning with '# Title1', then the following line with ,+1d, then subsequent lines until a blank line, but i see the following error:
sed: 1: "/^# Title1.*/,+1d { ...": extra characters at the end of d command
I've tried a few variations but no luck. Any help would be appreciated!
This is the kind of sed puzzle that makes me wish for a slightly different tool.
sed -n -e '/Title1/!{p;d;};n;' -e ':a' -e 'n;/./ba'
Loosely translated: "Don't print anything. If it doesn't contain 'Title1', then all right, print it, then start over with the next line. But if it does contain 'Title1', then grab the next line (which will be blank), enter a loop, and keep grabbing new lines until you come to the next empty line."
Using GNU sed
$ sed -z 's/# Title1[^#]*//' input_file
# Title2
line 1
line 2
line 3
This might work for you (GNU sed):
sed '/^# /h;G;/\n# Title1/!P;d' file
If a line begins # , make a copy.
Append the copy to each line and if that line does not contain \n# Title1, print it.
Delete all lines.
Alternative:
sed '/^# Title1/{:a;N;/\n#/!s/\n//;ta;D}' file

SED - using $ inserts string at beginning of line instead of end

I am not getting expected results from sed 's/$/2021-07-21/' demotoytable.csv
Before the command the top 3 lines look like:
urlhm|main_code|description|taxable|itemnum|xtras
t3mr.com/guitar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522831|bag
t3mr.com/guitar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522835|box
t3mr.com/guitar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522839|case
But after running the command sed 's/$/|2021-07-21/' demotoytable.csv
I get this result:
|2021-07-21code|description|taxable|itemnum|xtras
|2021-07-21itar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522831|bag
|2021-07-21itar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522835|box
|2021-07-21itar/qrc/G19RTE000000753|G19RTE0000007530|Promo_labor_day_006|Consignment|7522839|case
Any ideas on why this is happening, or better yet how to fix? I want each line to end w "|2021-07-21", not begin with it. On a Mac Pro running Big Sur
Thanks
Remove carriage returns and then add the texts you wish to add:
sed 's/\r$//; s/$/|2021-07-21/' demotoytable.csv
s/\r$// removes carriage returns at the end of lines, s/$/|2021-07-21/ in its turn appends the value of your choice at the end of lines.

A way to append the beginning of every line before a pattern to the end of each same line?

I am trying to copy the beginning of every line in a text file before a certain character to the end of the same line.
I've tried duplicating each line to the end of itself, and then deleting everything after the character, but the trouble is I haven't been able to figure out how to skip the first instance of the character so the result is that the duplicated text gets deleted as well as everything beyond the first instance of the character.
I've tried things like
sed '/S/ s/$/ append text/' sample.txt > cleaned.txt
but this only adds a fixed text. I've also tried using:
s/\(.*\)/\1 \1/
to duplicate the line, and then deleting everything after the S, but I can't figure out how to get it to go to the 3rd S not the 1st to start deleting.
What I have to start with:
dog 50_50_S5_Scale
cat 10_RV_S76_Scale
mouse 15_SQ_S81_Scale
What I'm trying to get:
dog 50_50_S5_Scale dog 50_50_
cat 10_RV_17_S76_Scale cat 10_RV_17_
mouse 15_EQ_S81_Scale mouse 15_EQ_
Where everything before the first S gets copied to the end of the line.
You may use
sed 's/\([^S]*\)S.*/& \1/' file
See the online demo
Details
\([^S]*\) - Capturing group 1 (\1): any 0+ chars other than S
S.* - S and the rest of the string (actually, line, since sed processes line by line by default).
The replacement is the concatenation of the whole match (&), space and Group 1 value.
You could try:
awk '{print $0 " " substr($0, 0, index($0,"S") - 1)}' file
We take the substring from the first character up to but not including the first occurance of "S".

sed n doesn't seem to work quite the way I thought it would

I was trying to copy an example I found here : http://www.grymoire.com/Unix/Sed.html#uh-35a
here is the sed pattern
/^begin$/,/^end$/{
/begin/n
/end/!d
}
here's the first file
begin
one
end
last line
and here's the second
begin
end
last line
when I run the sed on the first file it deletes what's between the begin/end and all is well. When I run it on the second, it appears to miss the "end" and deletes the rest of the file.
running on first file
$ sed -f x.sed a
begin
end
last line
running on second
$ sed -f x.sed b
begin
end
notice how "last line" is missing on the second run.
I thought that "n" would print the current pattern and suck in the next one. It would then hit the /end/ command and process that.
as it is, it seems like it's somehow causing the end of the range to be missed. Will somebody explain what is happening?
It should be:
/^begin$/,/^end$/{
/^begin$\|^end$/!d
}
Why was your command wrong?
The n command was wrong there. In the second example it will:
begin ---> n read next line(important: this does not affect the state of the range address (begin,end))
1a. end ---> /end/! does not apply. Don't delete the line
last line ---> /end/! applies. Delete the line. (sed is still searching for a line that contains end because the n command skipped that line)
found another way around after #hek2mgl 's help. I can add a branch around the 2nd statement. I actually need this because I want to see the begin label. so you can also do this:
/^begin$/,/^end$/{
/begin/{ b skip }
/end/!d
:skip
}
I think you were close to getting it to do what you wanted. When you want to delete the next line after a match you simply need to pull it in with the sed n and then hit it with a delete d.
It looks like you want to skip the line after the line that starts with begin unless it's end and print all the other lines.
If so, the following should suffice:
/^begin$/,/^end$/{
/begin/{n;/end/!d}
}
It works by skipping the next line after begin except if it starts with end (/end/!).
Also see: sed or awk: delete n lines following a pattern

In a sed transformation, how to apply a slightly different pattern just for the last line?

How can I turn this:
aaa
bbb
ccc
into this:
aaa,
bbb,
ccc
using sed?
Note how all lines end a comma, except the last one.
In my real problem I also do some regex substitutions on the lines. Is there a solution that doesn't duplicate them?
You could use:
sed '$q;s/$/,/'
If you want to apply a different substitution on the last line, you can still use the $ address:
sed '$s/$/;/;$q;s/$/,/'
The above will replace the end of the line with ; if it's the last line, otherwise it will use ,.
$s/$/;/ = at the last line, replace the end of the line with ;
$q = at the last line, quit
s/$/,/ = replace the end of the line with ,
The last s command will run for each line, but not for the last line in which the q command at 2. tells it to quit.
See:
Restricting to a line number
Ranges by line number
The q or quit command