LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   awk help (http://www.linuxquestions.org/questions/linux-newbie-8/awk-help-827929/)

jestinjoy 08-23-2010 02:30 AM

awk help
 
Hi ,
I am beginner with awk. I have a file like this.

Code:

        .long sys_restart_syscall        /* 0 - old "setup()" system call, used for restarting */
        .long sys_exit
        .long sys_fork
        .long sys_read
        .long sys_write
        .long sys_open                /* 5 */
        .long sys_close
        .long sys_waitpid
        .long sys_creat
        .long sys_link
        .long sys_unlink        /* 10 */

I would like to extract only restart_syscall,exit,fork,read,... from the file( these are system calls and i gave the system call table as input). For this i tried to replace first _ with a space and tried printing $3 but what i got as ouput is given below. I only want the output of the { print $3} to be written to the new file. Please help

Code:

        .long sys restart_syscall        /* 0 - old "setup()" system call, used for restarting */

        .long sys exit
exit
        .long sys fork
fork
        .long sys read
read
        .long sys write
write
        .long sys open                /* 5 */
open
        .long sys close
close
        .long sys waitpid
waitpid
        .long sys creat
creat
        .long sys link
link
        .long sys unlink        /* 10 */
unlink


My code is as follows
Code:

#!/usr/bin/awk -f
BEGIN {FS = "_"}
        sub(/_/," ")
        {FS = " "}
        {print $3}
END {}


grail 08-23-2010 03:17 AM

Well if I understand correctly, you wish to change the following:
Quote:

.long sys_close
into:
Quote:

close
Correct??

If so then you have 2 options, awk:
Code:

awk 'sub(/[^_]+_/,"")' file
or sed:
Code:

sed -r 's/[^_]+_//' file
Nice part about using sed is once you have what you like you can throw a '-i' at the start and the change will be made to the file.
Awk obviously you have to redirect and then perhaps rename.

Remembering also that both of the above will work on entire file, so you may need to edit it to only start and finish where you like :)

vinaytp 08-23-2010 05:31 AM

Hi,

This worked for me.
Code:

awk '{print $2}' file| cut -c 5-
As grail suggested,

Code:

awk 'sub(/[^_]+_/,"")' file
sed -r 's/[^_]+_//' file

work fine. But does not take care of removing /* */ comments which are appended in few lines.

jestinjoy 08-23-2010 07:06 AM

re
 
@grail It worked fine.
@vinaytp as suggested your script removed comments too.

But I have another question. When I run my script(not command). It gives the old and new one in a single file. Can I do the same thing as u suggested using script. What I did is given below.
My code

Code:

#!/usr/bin/awk -f
BEGIN {}
        sub(/_/," ")
        {print $3}
END {}

Then I executed the following command
Code:

./test.awk table.txt > test.txt
What I got As output is
Code:

        .long sys restart_syscall        /* 0 - old "setup()" system call, used for restarting */
restart_syscall
        .long sys exit
exit
        .long sys fork
fork
        .long sys read
read
        .long sys write
write
        .long sys open                /* 5 */
open
        .long sys close
close
        .long sys waitpid
waitpid
        .long sys creat
creat
        .long sys link
link
        .long sys unlink        /* 10 */

I want the things as given by you only not the .long lines. What should I do for this.

grail 08-23-2010 07:20 AM

The default action for any true statement if no other action is provided is to print.
The BEGIN and END in your script are redundant and do nothing.
Code:

sub(/_/," ")
This line says to remove the first underscore found in each line. The return from sub is the number of changes made, ie 1 or zero. All lines that return 1
will be printed.
Code:

{print $3}
Then you go on to print the third field as well.

Hence the double up of data.

vinaytp 08-23-2010 07:28 AM

You have modified the script given by grail which doesn's statisfy your requirement. You just have to use this way

Code:

#!/usr/bin/awk -f
sub(/[^_]+_/,"")

Now Try
Code:

./test.awk table.txt > test.txt

jestinjoy 08-23-2010 10:01 AM

Quote:

Originally Posted by grail (Post 4074988)
The default action for any true statement if no other action is provided is to print.
The BEGIN and END in your script are redundant and do nothing.
Code:

sub(/_/," ")
This line says to remove the first underscore found in each line. The return from sub is the number of changes made, ie 1 or zero. All lines that return 1
will be printed.
Code:

{print $3}
Then you go on to print the third field as well.

Hence the double up of data.

This solved my problem. I was unaware of the default printing thing.

@vinaytp Your code helped me to remove comment as well. Thanks for the help


All times are GMT -5. The time now is 11:47 PM.