Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash: shortest way to get n-th column of output

Tags:

bash

awk

People also ask

How do I print the nth line in bash?

N is the line number that you want. For example, tail -n+7 input. txt | head -1 will print the 7th line of the file. tail -n+N will print everything starting from line N , and head -1 will make it stop after one line.

How do I get the third column in Linux?

To get third column in tab delimited file, you can simply call it as cut -f3 <file> . Different delimiter can be passed via -d parameter, e.g.: cut -f3 -d: .


You can use cut to access the second field:

cut -f2

Edit: Sorry, didn't realise that SVN doesn't use tabs in its output, so that's a bit useless. You can tailor cut to the output but it's a bit fragile - something like cut -c 10- would work, but the exact value will depend on your setup.

Another option is something like: sed 's/.\s\+//'


To accomplish the same thing as:

svn st | awk '{print $2}' | xargs rm

using only bash you can use:

svn st | while read a b; do rm "$b"; done

Granted, it's not shorter, but it's a bit more efficient and it handles whitespace in your filenames correctly.


I found myself in the same situation and ended up adding these aliases to my .profile file:

alias c1="awk '{print \$1}'"
alias c2="awk '{print \$2}'"
alias c3="awk '{print \$3}'"
alias c4="awk '{print \$4}'"
alias c5="awk '{print \$5}'"
alias c6="awk '{print \$6}'"
alias c7="awk '{print \$7}'"
alias c8="awk '{print \$8}'"
alias c9="awk '{print \$9}'"

Which allows me to write things like this:

svn st | c2 | xargs rm

Try the zsh. It supports suffix alias, so you can define X in your .zshrc to be

alias -g X="| cut -d' ' -f2"

then you can do:

cat file X

You can take it one step further and define it for the nth column:

alias -g X2="| cut -d' ' -f2"
alias -g X1="| cut -d' ' -f1"
alias -g X3="| cut -d' ' -f3"

which will output the nth column of file "file". You can do this for grep output or less output, too. This is very handy and a killer feature of the zsh.

You can go one step further and define D to be:

alias -g D="|xargs rm"

Now you can type:

cat file X1 D

to delete all files mentioned in the first column of file "file".

If you know the bash, the zsh is not much of a change except for some new features.

HTH Chris


Because you seem to be unfamiliar with scripts, here is an example.

#!/bin/sh
# usage: svn st | x 2 | xargs rm
col=$1
shift
awk -v col="$col" '{print $col}' "${@--}"

If you save this in ~/bin/x and make sure ~/bin is in your PATH (now that is something you can and should put in your .bashrc) you have the shortest possible command for generally extracting column n; x n.

The script should do proper error checking and bail if invoked with a non-numeric argument or the incorrect number of arguments, etc; but expanding on this bare-bones essential version will be in unit 102.

Maybe you will want to extend the script to allow a different column delimiter. Awk by default parses input into fields on whitespace; to use a different delimiter, use -F ':' where : is the new delimiter. Implementing this as an option to the script makes it slightly longer, so I'm leaving that as an exercise for the reader.


Usage

Given a file file:

1 2 3
4 5 6

You can either pass it via stdin (using a useless cat merely as a placeholder for something more useful);

$ cat file | sh script.sh 2
2
5

Or provide it as an argument to the script:

$ sh script.sh 2 file
2
5

Here, sh script.sh is assuming that the script is saved as script.sh in the current directory; if you save it with a more useful name somewhere in your PATH and mark it executable, as in the instructions above, obviously use the useful name instead (and no sh).


It looks like you already have a solution. To make things easier, why not just put your command in a bash script (with a short name) and just run that instead of typing out that 'long' command every time?


If you are ok with manually selecting the column, you could be very fast using pick:

svn st | pick | xargs rm

Just go to any cell of the 2nd column, press c and then hit enter