While going through a shell script I came across the line
sed '1{/^$/d}' $file1 >> $file2
What is the significance of sed '1{/^$/d}'
here?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityRemove line 1 if it's empty....
1{
- if we're on line 1/^$/
- and it's an empty lined
- delete the line}
- end of conditionExample below.
$ cat x1
Hello
World
$ sed '1{/^$/d}' x1 >x2
$ cat x2
Hello
World
$
The GNU sed
expression
1{/^$/d}
which is more portably written
1{/^$/d;}
or
1 {
/^$/ d
}
is in two parts:
1 {...}
/^$/ d
The first part triggers the command within braces if the current line is the first line of input.
The second part triggers the d
command if the current line is empty, i.e. if the start of the line, ^
, is immediately followed by the end of the line, $
. The d
command discards the current input and immediately starts the next cycle (which means it skips to the following line of input and starts evaluating the expression from the very start).
Both 1
and /^$/
are addresses that affect what lines the subsequent command will be applied to.
In short, your sed
command deletes the first line of input if it's empty while avoiding deleting any other empty line.
The expression
/^$/ { 1 d; }
would have done the same thing but would require sed
to perform a regular expression match on each line of input and would therefore potentially be more expensive (although it's questionable if you would notice any difference unless your input was huge and your computer very slow).
Apart from that, you should most likely quote the variables in your command, and the since we don't know what's in $file1
, we'd better protect the command from accidentally interpreting the value as a set of options if it starts with a dash:
sed -- '1 { /^$/ d; }' "$file1" >>"$file2"
or,
sed -e '1 { /^$/ d; }' -- "$file1" >>"$file2"
or, make sed
read from standard input,
sed '1 { /^$/ d; }' <"$file1" >>"$file2"
See also
empty lines
lines that are marked as$
when runningsed -n l file1
it won't remove lines that have...spaces...
in them. Therefore you could considersed '1{/^$/d;/\s*/d;}' file1