I have a file like this -
1,[test1] Joe,OK
2,[test2] Jack,OK
3,[test3] Tom,FAIL
I am printing the file like this -
cat file | awk -F"," '{ print "||" $1 "||" $2 "||" $3 "||" }'
I would like the output file like this -
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
i.e. [test1] Joe is modified to Joe how can we do something like this on each column.
echo "[test1] Joe" | sed 's/\[.*\]\s//g'
Which gives me only Joe how can I combined this with the other columns?
In awk with the correct spacing:
$ awk -F, '{split($2,a," ");printf "||%s || %-4s || %s ||\n",$1,a[2],$3}' file
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
You was almost there with your attempt, you should take a look at the printf and split functions.
With sed:
sed 's/\[[^]]*\]//;s/^/|| /;s/$/ ||/;s/,/ || /g' input
Output
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
To do in-place start with sed -i
One way:
awk -F, '{$1=OFS""$1;$NF=$NF""OFS;sub(/.* /,"",$2);}1' OFS=" || " file
On running the above:
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
awk -F"," '{gsub(/,\[.*?\]|,|^|$/," || ",$0) }1' your_file
or
perl -plne 's/^|,/ || /g;s/\[.*?\]//g' your_file
tested below:
> cat temp
1,[test1] Joe,OK
2,[test2] Jack,OK
3,[test3] Tom,FAIL
> perl -plne 's/^|,|$/ || /g;s/\[.*?\]//g' temp
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
> awk -F"," '{gsub(/,\[.*?\]|,|^|$/," || ",$0) }1' temp
|| 1 || Joe || OK ||
|| 2 || Jack || OK ||
|| 3 || Tom || FAIL ||
>
If you want to replace the file inplace use:
perl -i -plne 's/^|,|$/ || /g;s/\[.*?\]//g' your_file
Related
I have the following command:
ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}};'
How do i excute this linux command from rakeFile.
I tried:
task :kill_process do
`ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}};'`
end
But on executing it's giving error:
awk: cmd. line:1: {if( $8~"java" || $8~"glassfish" || $8~"ruby" || $8~"god" || $8~"couch"){printf("Killing : %s
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: {if( $8~"java" || $8~"glassfish" || $8~"ruby" || $8~"god" || $8~"couch"){printf("Killing : %s
awk: cmd. line:1: ^ syntax error
I got the solution for my problem:
Thanks to #Yurii Verbytskyi
task :kill_process do
system %q(ps -ef | awk '{if( $8~"java" || $8~"ruby" || $8~"god"){printf("Killing : %s \n",$2);{system("kill -9 "$2)};}}')
end
Try this one.
task :kill_process do
system("ps -ef | awk '{if( $8~\"java\" || $8~\"ruby\" || $8~\"god\"){printf(\"Killing : %s \\n\",$2);{system(\"kill -9 \"$2)};}};'")
end
We need to escape special chars like \n
This is my script and it works perfect for one file:
awk 'BEGIN {while (getline < "eq5_1.gro") {if ($1 ~ /MGD/ && ($NF < 3.477 || $NF > 7.947 || $(NF-1) < 12.741 || $(NF-1) > 22.240)) name[$1]=$1}} {if ($1 != name[$1]) print}'
eq5_1.gro | tee eq6_1.gro
I want to use this script on 100 files, so I wrote this script.
num=1
for num in {1..100}
do
awk 'BEGIN {while (getline < "eq5_"'$num'".gro") {if ($1 ~ /MGD/ && ($NF < 3.477 || $NF > 7.947 || $(NF-1) < 12.741 || $(NF-1) > 22.240)) name[$1]=$1}} {if ($1 != name[$1]) print}' eq5_$num.gro | tee eq6_$num.gro
done
I have a problem with this part of code
(getline < "eq5_"'$num'".gro")
How can I put here number as a string? I want to have here eq5_1.gro the eq5_2.gro etc. for all 100 files
I also try this, didn't work
awk -v var="$num" 'BEGIN {while (getline < "eq5_"'$var'".gro")
It seems like you ought to just be doing: awk '...' eq5_*.gro, but I'm not going to look to closely at your awk or question the wisdom of doing all your processing in a BEGIN clause (but I'll mention that it's bad practice). But you can do:
for num in {1..100}; do
awk -v file="eq5_${num}.gro" 'BEGIN {while (getline < file) ...} '
done
Reformatting for readability
awk '
BEGIN {
while (getline < "eq5_1.gro") {
if ($1 ~ /MGD/ && ($NF < 3.477 || $NF > 7.947 || $(NF-1) < 12.741 || $(NF-1) > 22.240))
name[$1]=$1
}
}
{if ($1 != name[$1]) print}
' eq5_1.gro
So you want to print the lines that don't match that condition?
Your awk command can be greatly simplified, and you don't need to process the file twice.
awk '! ($1 ~ /MGD/ && ($NF < 3.477 || $NF > 7.947 || $(NF-1) < 12.741 || $(NF-1) > 22.240))' eq5_1.gro
Refer to the awk info page
I need to sort a table based on two columns, one column is numerical and while other is string. I need to have descending order for numerical while I would like to have alphabetical for string. Use of '-r' option for sort does work for numerical but it gets applied for sting too. I wonder how to apply reverse option only for one column and not the other.
Cmd: sort -r -k5 -k3 -k1
Data:
Input
il || 2 | 3 ||
we || 2 | 2 ||
dt || 0 | 2 ||
di || 0 | 2 ||
cs || 16 | 1 ||
fd || 5 | 1 ||
df || 14 | 0 ||
np || 9 | 0 ||
dt || 9 | 0 ||
ta || 0 | 0 ||
rt || 0 | 0 ||
ps || 0 | 0 ||
Expected
il || 2 | 3 ||
we || 2 | 2 ||
di || 0 | 2 ||
dt || 0 | 2 ||
cs || 16 | 1 ||
fd || 5 | 1 ||
df || 14 | 0 ||
dt || 9 | 0 ||
np || 9 | 0 ||
ps || 0 | 0 ||
rt || 0 | 0 ||
ta || 0 | 0 ||
This works for me
$ sort -rk5 -k3 -k1b input
Output:
il || 2 | 3 ||
we || 2 | 2 ||
di || 0 | 2 ||
dt || 0 | 2 ||
cs || 16 | 1 ||
fd || 5 | 1 ||
df || 14 | 0 ||
dt || 9 | 0 ||
np || 9 | 0 ||
ps || 0 | 0 ||
rt || 0 | 0 ||
ta || 0 | 0 ||
What I wanted to do, is find out all the entry in my file when the first element in each line, with "hh:mm:ss" format, is between two hours
File format:
14:40:00 user1 load xxxx xxxx xxxxx
14:40:02 user2 change xxx xxx xxxxx
15:03:04 user1 change xxx xxx xxxxx
so on...
I would like to get al the entry between 14:40:00 and 15:00:00.
I was thinkig to do it with the following command, but I dont know how can follow with the fiter.
cat app.log | grep change | awk '{print $1 if .....}'
After that I would like to print whole line. Could somebody tell me how can I do conditional filter in command line?
Thanks.
This can be a way:
$ awk -F: '($1==14 && $2>=40) || ($1==15 && $2==0)' file
14:40:00 user1 load xxxx xxxx xxxxx
14:40:02 user2 change xxx xxx xxxxx
I also see you are grepping change. You can do it all together:
$ awk -F"[: ]" '/change/ && (($1==14 && $2>=40) || ($1==15 && $2==0))' app.log
14:40:02 user2 change xxx xxx xxxxx
Explanation
-F"[: ]" sets space or : as field delimiters. Is not entirely necessary as you could just use -F:, but it allows you to "play" with the rest of the fields if you want to.
'($1==14 && $2>=40) || ($1==15 && $2==0)' are the possible conditions to match: hour 14 + minute >=40 or hour 15 + minute == 0.
awk '"14:40:00" <= $1 && $1 <= "15:00:00"' app.log
If you want to pass in the start and end times dynamically:
start=14:40:00
end=15:00:00
awk -v start=$start -v end=$end 'start <= $1 && $1 <= end' app.log
If, as you show, you also only want "change" events:
awk -v start=$start -v end=$end 'start <= $1 && $1 <= end && /change/' app.log
awk -v start=$start -v end=$end 'start <= $1 && $1 <= end && $3 == "change"' app.log
With perl it would be:
perl -n -e '/(\d\d:\d\d:\d\d) \S+ (\S+) / && $2 eq "change" && $1 ge "14:40:00" && $1 le "15:00:00" && print $_' < app.log
Or slightly more readable:
perl -n -e '/(\d\d:\d\d:\d\d) \S+ (\S+) / ' \
-e '&& $2 eq "change" ' \
-e '&& $1 ge "14:40:00" ' \
-e '&& $1 le "15:00:00" ' \
-e '&& print $_' < app.log
I have a file with some data like this:
1, 3, 0, 0, 0
0, 4, 5, 0, 5
2, 6, 0, 1, 0
I would like to write a shell script to delete all the lines where the 3rd argument is 0 (here line 1 and 2)
I already know that
sed -i '/0/d' file.txt
but I don't know how I can select the 3rd arguments whatever the others one.
Do you have an idea?
Awk may be a better tool than sed for this task:
awk -F' *, *' '$3 != 0 {print}' FILE
But sed can do it:
sed -i '/^[0-9][0-9]*, [0-9][0-9]*, 0,/d' FILE
sed -iE '/^([^,]+,){2} 0,/d' file
explained with explain.py:
sed -iE '/^([^,]+,){2} 0,/d' file
\_/ || ||| || || \_/ | |
| || ||| || || | | \- delete command
| || ||| || || | |
| || ||| || || | \- followed by blank zero komma
| || ||| || || |
| || ||| || || \- two times this inner pattern
| || ||| || ||
| || ||| || |\- followed by a comma
| || ||| || |
| || ||| || \- at least one of them
| || ||| ||
| || ||| |\- komma
| || ||| |
| || ||| \- not
| || |||
| || ||\- start of pattern, group of characters, which are
| || ||
| || |\- at begin of line
| || |
| || \- start of pattern for delete command
| ||
| |\- Extended regexp (parenthesis and braces without masking)
| |
| \- inplace changes
|
\- run sed
awk with in place editing (similar to sed -i)
awk '$3!="0,"{print $0>FILENAME}' file
Ruby(1.9+)
ruby -ane 'print unless $F[2]=="0," ' file