This question already has answers here:
Printing with sed or awk a line following a matching pattern
(9 answers)
Closed 4 years ago.
I have a text file that looks like
file:/path/to/file
..
..
DA:34,0,0
DA:86,0,0
DA:87,0,0
..
DA:89,0,0
file:/path/to/file
..
DA:23,0,1
..
DA:24,0,1
DA:25,0,1
..
I just want to keep the first line beginning with "DA" after the line beginning with "file". Other lines starting with "DA" have to be deleted. There are a lot of other lines (I marked them with ".."), they also need to be kept.
The result should look like this:
file:/path/to/file
..
..
DA:34,0,0
..
file:/path/to/file
..
DA:23,0,1
..
..
Can anybody help me? I would be really grateful. Thanks
This is very closely related to Printing with sed or awk a line following a matching pattern.
What you are after is:
awk '/^file/{f=1}(f&&/^DA/){f=0;print}!/^DA/' file
How does this work?
/^file/{f=1}: If you find a line which starts with the word "file", set a flag f to 1
(f&&/^DA/){f=0;print}: If the flag f is not zero, and the line starts with DA, print the line and set the flag to zero. This makes sure you only print the first DA after file.
!/^DA/: print all the lines that do not start with DA
A shorter version:
awk '/^file/{f=1}(f--&&/^DA/);!/^DA/' file
Related
I just need to move a line up in sed. I can select the line with
sed -i '7s///'
I need to move line 7 up 2 lines so it will be line 5.
I can't find anything on the internet to do this without complicated scripts, I can't find a simple solution of moving a specific line a specific number of times.
seq 10|sed '5{N;h;d};7G'
when up to line 5 append next line(line 6) into pattern space then save them into hold space and delete them from pattern space; up to line 7 then append the hold space content("5\n6") behind the line 7; now, pattern space is "7\n5\n6";finally,sed will print the pattern space at the end of current cycle by default(if no "-n" parameter)
ed is better at this, since it has a "move" command that does exactly what you want. To move line 7 to be the line after line 4, just do 7m4. ed doesn't write the data back by default, so you need to explicitly issue a w command to write the data:
printf '7m4\nw\n' | ed input
Although it is perhaps better to use a more modern tool:
ex -s -c 7m4 -c w -c q input
This question already has answers here:
Usage of :- (colon dash) in bash
(2 answers)
Closed 1 year ago.
I ran across the following Bash function which was suggested as a useful alias to add to the .bashrc file. It lists the last 13 files in a directory that were modified.
I don't understand what is being done with the ${1:-.} argument, though. It looks like some kind of substring extraction, but I couldn't find the meaning of -. in the Advanced Bash Scripting Manual.
I tried the command in a few directories and didn't notice any difference between the output when I removed this argument. My guess is that it's there to prevent an error when encountering some specific type of file or file name. What is it doing? And what is the purpose of including it in the command?
function lst()
{
ls -lashtg ${1:-.} | head -13
}
$1 is the first command line argument. Im sure you know.
${1:-.} simply puts a . when no first line argument is given.
Thus
lst
Translates to
ls -lashtg . | head -13
It would workout without the substitution I guess. But I also guess that this is just there as a best practice
This question already has answers here:
Unix command to prepend text to a file
(21 answers)
Closed 2 years ago.
Real nit picky Linux question.
I have a text file, call it userec. I also have a string variable 'var_a'.
I want to concatenate the string value, let just say it's 'howdy' to the top of the text file.
So something like
echo $var_a | cat usrec > file_out
where it pipes the output from the echo $var_a as a file and adds it to the top of file_out and then adds the rest of the usrec file.
So if the userec file contains just the line 'This is the second line' then the contents of file_out should be:
howdy
This is the second line.
problem is that's not what the command is doing and I do not want to create a variable to store var_a in. This is running from a script and I don't want to create any extra flack to have to clean up afterwards.
I've tried other variations and I'm comming up empty.
Can anyone help me?
If you give cat any file names then it does not automatically read its standard input. In that case, you must use the special argument - in the file list to tell it to read the standard input, and where to include it in the concatenated output. Since apparently you want it to go at the beginning, that would be:
echo $var_a | cat - usrec > file_out
I would simply do :
echo $var_a > file_out
cat usrec >> file_out
I just need to move a line up in sed. I can select the line with
sed -i '7s///'
I need to move line 7 up 2 lines so it will be line 5.
I can't find anything on the internet to do this without complicated scripts, I can't find a simple solution of moving a specific line a specific number of times.
seq 10|sed '5{N;h;d};7G'
when up to line 5 append next line(line 6) into pattern space then save them into hold space and delete them from pattern space; up to line 7 then append the hold space content("5\n6") behind the line 7; now, pattern space is "7\n5\n6";finally,sed will print the pattern space at the end of current cycle by default(if no "-n" parameter)
ed is better at this, since it has a "move" command that does exactly what you want. To move line 7 to be the line after line 4, just do 7m4. ed doesn't write the data back by default, so you need to explicitly issue a w command to write the data:
printf '7m4\nw\n' | ed input
Although it is perhaps better to use a more modern tool:
ex -s -c 7m4 -c w -c q input
What is the special character which indicate first ?
if we do
$ vi .bashrc
$ source !$
this !$ will replaced by .bashrc
because ! means previous line(am I correct?), $ means last word (for sure)
then what is first?
I want to insert some string in every line in vi editor using
:%s/find-key-word/replaced-keyword/g
in here, if I put
:%s/$/example/g
in vi editor, it will append in all lines with example.
I want to insert all in front of all string every line.
I know I can use visual block (ctrl+v) and select all front lines and insert (shift+i) insert some word and escape(esc) will do the same... but I want to do in one shot..
please let me know how to do..
Thanks in advance
There are two questions, so you are getting two kinds of answers :)
The bash command history has only a passing similarity to the vi regular expression syntax.
^ is the beginning of line in vi. $ is the end of line in vi.
!!:0 is one way of accessing the first word of the previous command in bash
!$ is one way of accessing the last word of the previous command in bash
To indicate beginning of line, the symbol used is:
^
See an example:
$ cat a
hello!
this is me
testing some
stuff
$ sed 's/^/XXX/' a
XXXhello!
XXXthis is me
XXXtesting some
XXXstuff
The character you are looking for is ^.
For example, :%s/^/example/g will prepend all lines with the string example.
In bash, !^ refers to the first argument of the previous command, and !$ the last argument.