ahchrist
ahchrist

Reputation: 166

want to alter field separator to allow spaces in particular data field

I want to hack a bash script that outputs a user's PIDs in a yad pop-up with option to select and kill PID if desired. But script uses awk to format data and I am unfamiliar with awk. I would use sed instead but data has 11 fields and sed only allows 9 buffers.

My problem with the awk format is the last field, $11 is the command details and it gets chopped off after the first space in the description, which I don't want. I guess I might be able to replace all the spaces after the first 10, recognized as field separators to prevent command description details from getting lopped off after the first space. But that seems kind of hacky and I am sure there is a slicker way to do it with the awk command from the original script:

function gen_data() {

ps aux | tail -n +2 > "$TMPFILE" 
sed -ri "/$USER/!d" "$TMPFILE"
sed -ri "/$procName/!d" "$TMPFILE"
cat "$TMPFILE"

cat "$TMPFILE" | awk -F' ' '{print " " "\n" $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7 "\n" $8 "\n" $9 "\n" $10 "\n" $11}' > "$OUTFILE" 
#`sed` edit
#cat "$TMPFILE" | sed -r 's/^([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}[^ ]*[ ]{1,}[^ ]*[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}(.*)$/\1\n\2\n\3\n\4\n\5\n\6\n\7\n\8\n\9/' > "$OUTFILE" 
cat "$OUTFILE"

}

I wonder if anyone minds helping out on this?

UPDATE:
I managed to get the output I want by employing a while loop to change the first ten spaces in the $TMPFILE before awk processes it to tabs, which keeps all the spaces in the PID description in tact:

function gen_data() {

    ps aux | tail -n +2 > "$TMPFILE" 
    sed -ri "/$USER/!d" "$TMPFILE"
    sed -ri "/$procName/!d" "$TMPFILE"
    cat "$TMPFILE"
    cntr=10
    while [[ "$cntr" -gt 0 ]] ; do
        sed -ri 's/[ ]{1,}/\t/' "$TMPFILE"
        ((cntr--))
    done

    cat "$TMPFILE" | awk -F '   ' '{print " " "\n" $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7 "\n" $8 "\n" $9 "\n" $10 "\n" $11}' > "$OUTFILE"
}

I would still be interested in any alternate/better ways it might be done?

Upvotes: 2

Views: 92

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207375

EDITED

Sorry, I am being stupid today! You can just use substr() to get the command, like this, assuming it starts in column 70:

awk '{command=substr($0,70); print command}' $TEMPFILE

ANOTHER OPTION

You could also grab the command corresponding to a given process id (pid) like this:

ps -p <PID> -xo command=

And rather than deleting all lines not belonging to a given user (like you do with your sed), you could be more specific in the first place using a command like this:

ps -u <uid> -xo pid=,uid=,command=

ORIGINAL ANSWER

I think you could use the FIELDWIDTHS variable to tell awk where to split your fields, rather than using spaces. It is a GNU extension and I do not know the widths of the fields on your ps aux command so you will have to count them :-)

awk 'BEGIN{FIELDWIDTHS="14 8 6 6 6 8 6 8 6 8 200"}{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11}' $TMPFILE

Just make the width of the last field enormous to catch all the command.

Upvotes: 2

Related Questions