Can you explain this sed one-liner?
This will do the same job as tac
, i.e. revert the order of rows.
Rewriting the sed script to pseudocode, it means:
$line_number = 1;
foreach ($input in $input_lines) {
// current input line is in $input
if ($line_number != 1) // 1!
$input = $input + '\n' + $hold; // G
$hold = $input; // h
$line_number++
}
print $input; // $p
As you can see, the sed language is very expressive :-) the 1!
and $
are so called addresses, which put conditions when the command should be run. 1!
means not on the first row, $
means at the end. Sed has one auxiliary memory register which is called hold space
.
For more information type info sed
on linux console (this is the best documentation).
-n
disables the default print $input
command in the loop itself.
The terms pattern space
and hold space
are equivalents of the variables $input
and $hold
(respectively) in this example.
Confusing Sed One-Liner in Makefile Tutorial
The sed pattern will be processed by make first, so if the rule that it applies to is trying to build foo.P
then $@
will be translated to foo.P
and $*
to foo
. This means that the actual sed command will be something like:
sed 's/\(foo\)\.o[ :]*/\1.o foo.P : /g' < foo.d > foo.P
\(foo\)
matches foo
exactly and sets the first replacement to what matches (i.e. foo
) \.
matches a literal dot and [ :]*
matches any number of spaces and colons.
As you can see the \1
replacement is a bit redundant as the matched string is fixed. This would have worked just as well.
sed 's/foo\.o[ :]*/foo.o foo.P : /g' < foo.d > foo.P
which could have been made from:
sed 's/$*\.o[ :]*/$*.o $@ : /g' < $*.d > $@
Display one line of two with sed
sed -n 'p;n'
-n
suppresses all output that isn't explicitly printed.
'p;n'
is the sed script to run on each input line. The semicolon is a separator between two commands, p
and n
.
p
prints the current line, without moving to the next line.
n
moves to the next line without printing anything.
Once these two commands have been run on the current line, sed moves on to the next line, and then runs the script again on this new line. This script will keep running until there are no more input lines. The effect of the script is to keep printing, then skipping lines.
p;n;n
This is mostly the same script, but it skips two lines instead of one.
p;p;n
This is mostly the same script, but it prints the line twice before skipping it.
why it isn't printing the first and second line, and hide the third one ?
Because p
doesn't advance sed forward a line, only n
(or reaching the end of the script) does that.
(It might be helpful to note that sed -n 'p'
prints every line without skipping any, sed -n 'p;p;p'
prints every line three times, and sed -n 'p;n;p'
is equivalent to sed -n 'p'
.)
sed one liner to delete replace and merge
I believe this might be what you are after:
sed '/^$/d;:a;/\r\n*$/{N;ba};s/\r\n*//;s/MB//g;s/-/0/g' file
The idea is the following:
- read a line in the pattern-space
/^$/d
: if the line is empty, delete it and restart the cycle:a;/\r\n*$/{N;ba};
: if the pattern space ends withCR
followed by one or moreLF
, read the next line, append anLF
and the line to the pattern-space. Keep on doing that until the pattern space ends with something else.s/\r\n*//
: Delete allCRLF*
sequences.s/MB//g;s/-/0/g
: perform final substitutions.
sed, how to replace one line with 2 line?
Try this if you're in bash:
sed -i.bak $'s/You are good/You are good\\\nYou are the best/g' /output.txt
Strange, eh? But seems to work. Maybe sed can't handle the newline correctly so it needs to be escaped with another backslash, thus \\
which will become a single \
before going to sed.
Also, note that you were not passing an extension to -i
.
Edit
Just found another solution. As the newline needs to be escaped when passing to sed (otherwise it thinks it's a command terminator) you can actually use single quotes and a return, just insert the backslash before entering the newline.
$ echo test | sed 's/test/line\
> line'
line
line
sed only works on one line
You need to make the whitespace in front of the ip_forward
optional, by adding a *
after \s
.
In your sample input, there is no whitespace character in front of ip_forward
, so your expression doesn't match because it is requiring at least the whitespace character.
#!/bin/bash
#Locations
LocationOne="$SERVER_DIR/config.yml"
if [ -f "$LocationOne" ]
then
cd "$SERVER_DIR"
sed -i "s/^.*\s*host:.*/ host: $IP:$PORT/g" $SERVER_DIR/config.yml
sed -i "s/^.*\s*ip_forward: false/ ip_forward: true/g" $SERVER_DIR/config.yml
fi
On a separate note, you're matching .*
in front of ip_forward
which is any number of any characters (excluding newline), and I'm not sure if that was the intent.
sed one-liner to convert all uppercase to lowercase?
With tr
:
# Converts upper to lower case
$ tr '[:upper:]' '[:lower:]' < input.txt > output.txt
# Converts lower to upper case
$ tr '[:lower:]' '[:upper:]' < input.txt > output.txt
Or, sed
on GNU (but not BSD or Mac as they don't support \L
or \U
):
# Converts upper to lower case
$ sed -e 's/\(.*\)/\L\1/' input.txt > output.txt
# Converts lower to upper case
$ sed -e 's/\(.*\)/\U\1/' input.txt > output.txt
Translating a sed one-liner into awk
$ cat tst.awk
BEGIN {
split("1 AAA 5 EEE 26 ZZZ",tmp)
for (i=1; i in tmp; i+=2) {
dict[tmp[i]] = tmp[i+1]
}
FS="[ =]"
OFS="="
}
$1 == "[PREFIX]" {
print $1
for (i=2; i<NF; i+=2) {
print " " ($i in dict ? dict[$i] : $i), $(i+1)
}
next
}
{ print }
$ awk -f tst.awk file
Normal line
Another normal line
[PREFIX]
AAA=Something
EEE=SomethingElse
ZZZ=42
Normal line again
Convert sed One-Liner to perl
This perl one-liner should work:
perl -pe 's/:\n$/: /' file
Looking into the table etl_f_gl_balance
# of -1 values in etl_f_gl_balance.row_key: 0
# of -1 values in etl_f_gl_balance.ledger_key: 1020
# of -1 values in etl_f_gl_balance.gl_account_key: 1020
# of -1 values in etl_f_gl_balance.legal_entity_key: 1020
# of -1 values in etl_f_gl_balance.cost_center_key: 995
# of -1 values in etl_f_gl_balance.natural_account_key: 1020
# of -1 values in etl_f_gl_balance.posting_period_fiscal_key: 5
# of -1 values in etl_f_gl_balance.posting_period_key: 5
Related Topics
Data Pointers in Inode Data Structure
Process Scheduling from Processor Point of View
Linux Set End of File (Shrink, Truncate, Cut Out Some Data @ End)
Passing a Password to "Su" Command Over Sshexec from Ant
How to Reset Tty After Exec-Ed Program Crashes
Placement of '-L' Option in Gcc
How to Delete X Number of Files in a Directory
Killing a Daemon Using a Pid File
Sigbus While Doing Memcpy from Mmap Ed Buffer Which Is in Ram as Identified by Mincore
Get Canonical Path from Pathname
Bash: Ctrl+C During Input Breaks Current Terminal
Qfiledialog: How to Filter Only Executables (Under Linux)
Infinite Loop Receive from Serial Port
Symbol Lookup Error Undefined Symbol, But All Symbols Seem to Be Present