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

后端 未结 8 1807
春和景丽
春和景丽 2020-11-28 03:29

Let\'s say that during your workday you repeatedly encounter the following form of columnized output from some command in bash (in my case from executing svn st

相关标签:
8条回答
  • 2020-11-28 03:54

    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

    0 讨论(0)
  • 2020-11-28 03:55

    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\+//'

    0 讨论(0)
  • 2020-11-28 04:04

    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).

    0 讨论(0)
  • 2020-11-28 04:06

    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

    0 讨论(0)
  • 2020-11-28 04:14

    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
    
    0 讨论(0)
  • 2020-11-28 04:14

    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?

    0 讨论(0)
提交回复
热议问题