Removing part of a line? [bash]

115 views Asked by At

I'm writing my own ps-command in bash, but i'm having some trouble getting cmdline. This is my code:

get_cmdline(){
if [ -f "/proc/$1/cmdline" ]; then
cat /proc/$1/cmdline | cut -d " " -f 1
else echo n/a
fi
}

But this is what i'm getting:

/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type=zygote

What is the easiest way to remove '--type=zygote'?

PS: I don't know command sed, so if used, I would greatly appreciate a detailed explanation

Thanks a lot

5

There are 5 answers

1
Hackaholic On BEST ANSWER

using awk:

echo "/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type=zygote" | awk -F "--" '{print $1}'
/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome

awk will delimit the record on '--'. then i am printing field one only 1st field

using sed:

echo "/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type=zygote" | sed 's/--.*//g'
/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome

using pattern matching:

a="/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type=zygote" 
echo ${a%--*}
/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome
0
Dinesh On

inputs to cut need some reformatting. Use

cat /proc/$1/cmdline | cut -d\  -f 1

Mind ya, there is a space after the backslash.

BTW I see you asked "What is the easiest way to remove '--type=zygote'?" That is a different question, and are you looking for some sed-like thing?

0
Khanna111 On

That should do it using sed:

$ echo "/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type=zygote" | sed "s/--type.*$//"
/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome

If you would like to use cut then:

$ echo "/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome--type" | rev | cut -d'-' -f3- | rev
/opt/google/chrome/chrome-sandbox/opt/google/chrome/chrome
0
striving_coder On

If you want to remove exactly '--type=zygote' as you said in your post, you should use sed like this:

cat /proc/$1/cmdline | cut -d " " -f 1 | sed 's/--type=zygote//'

The command to sed is specified in the single quotes. s is the substitution command, its format is: s/oldstuff/newstuff/ to substitute oldstuff with newstuff; if newstuff is empty line, the result is oldstuff being removed (you effectively substitute oldstuff with the empty line), which is what we do in our example.

If you want more universal action, e.g. removing the rest of the line starting with --, you should do:

cat /proc/$1/cmdline | cut -d " " -f 1 | sed 's/--.*//'

The only difference to the previous example here is that we use regular expression where . stands for "any symbol" and * specified any number of the preceding symbol, so .* means "any number of any symbols" and --.* means "-- followed by any number of any symbols".

sed is pretty powerful tool (and fun too!) so might want to take some time to read up on it.

Hope that helps!

1
Ray On

/proc/*/cmdline has commands and arguments separated by nulls. You could use sed to remove everything after the first null:

sed 's/\x00.*//' < /proc/$1/cmdline

Or you could use xargs to reformat the nulls into spaces, then use cut or sed or awk:

xargs -0 echo < /proc/$1/cmdline | cut -d" " -f1
xargs -0 echo < /proc/$1/cmdline | sed 's/ .*//'
xargs -0 echo < /proc/$1/cmdline | awk '{print $1}'

(I'm not using cat to print out the cmdline files because that's unnecessary process activation; you can just use redirects to get info from a file into your command.)

Or even better, for a pure Bash solution, use read with a nil delimiter:

IFS= read -r -d '' foo < /proc/$1/cmdline
printf '%s\n' "$foo"

Note that /proc is not available everywhere. (I don't know how to get command line information otherwise, though.)