1

Background

I have a file, named yeet.d, that looks like this

JET_FUEL = /steel/beams
ABC_DEF = /michael/jackson
....50 rows later....
SHIA_LEBEOUF = /just/do/it
....73 rows later....
GIVE_FOOD = /very/hungry
NEVER_GONNA = /give/you/up

I am familiar with the f and d options of the cut command. The f option allows you to specify which column(s) to extract from, while the d option allows you to specify what the delimiters.

Problem

I want this output returned using the cut command.

/just/do/it

From what I know, this is part of the command I want to enter:

cut -f1 -d= yeet.d

Given that I want the values to the right of the equals sign, with the equals sign as the delimiter. However this would return:

/steel/beams
/michael/jackson
....50 rows later....
/just/do/it
....73 rows later....
/very/hungry
/give/you/up

Which is more than what I want.

Question

How do I use the cut command to return only /just/do/it and nothing else from the situation above? This is different from How to get second last field from a cut command because I want to select a row within a large file, not just near from the end or the beginning.

isakbob
  • 1,439
  • 2
  • 17
  • 39

2 Answers2

2

This looks like it would be easier to express with awk...

# awk -v _s="${_string}" '$3 == _s {print $3}' "${_path}"

## Above could be more _scriptable_ form of bellow example

awk -v _search="/just/do/it" '$3 == _search {print $3}' <<'EOF'
JET_FULE = /steal/beams
SHIA_LEBEOUF = /just/do/it
NEVER_GONNA = /give/you/up
EOF

## Either way, output should be similar to
##  /just/do/it
  • -v _something="Some Thing" bit allows for passing Bash variables to awk

  • $3 == _search bit tells awk to match only when column 3 is equal to the search string

    • To search for a sub-string within a line one can use $0 ~ _search
  • {print $3} bit tells awk to print column 3 for any matches

  • And the <<'EOF' bit tells Bash to not expand anything within the opening and closing EOF tags

... however, the above will still output duplicate matches, eg. if yeet.d somehow contained...

JET_FULE = /steal/beams
SHIA_LEBEOUF = /just/do/it
NEVER_GONNA = /give/you/up
AGAIN = /just/do/it

... there'd be two /just/do/it lines outputed by awk.

Quickest way around that would be to pipe | to head -1, but the better way would be to tell awk to exit after it's been told to print...

_string='/just/do/it'
_path='yeet.d'

awk -v _s="${_string}" '$3 == _s {print $3; exit}' "${_path}"

... though that now assumes that only the first match is wanted, obtaining the nth is possible though currently outside the scope of the question as of last time read.


Updates

To trip awk on the first column while printing the third column and exiting after the first match may look like...

_string='SHIA_LEBEOUF'
_path='yeet.d'

awk -v _s="${_string}" '$1 == _s {print $3; exit}' "${_path}"

... and generalize even further...

_string='^SHIA_LEBEOUF '
_path='yeet.d'

awk -v _s="${_string}" '$0 ~ _s {print $3; exit}' "${_path}"

... because awk totally gets regular expressions, mostly.

S0AndS0
  • 860
  • 1
  • 7
  • 20
  • 1
    So this is absolutely a great way to answer the question hence +1. However, in my context, I really only know the left side (SHIA_LEBEOUF) and want to obtain the right side. The answer by @flappix contains a way that does this more generically. – isakbob May 30 '19 at 19:13
  • Thanks for the feedback @isakbob, I've updated my answer to hopefully show ya that `awk` is something worth looking into. There's an entire [scripting](https://www.gnu.org/software/gawk/manual/html_node/Executable-Scripts.html) language available, so as projects grow it's possible to make reusable bits... and that's not even getting into how much faster things can run by adopting `awk` into the workflow... Let us know with an `awk` question if ya get stuck on some edge-case, perhaps tag me if ya wish, as it can sometimes be difficult to find up-to date documentation on such things. – S0AndS0 May 30 '19 at 19:43
1

It depends on how you want to identify the desired line.

You could identify it by the line number. In this case you can use sed

cut -f2 -d= yeet.d | sed '53q;d'

This extracts the 53th line.

Or you could identify it by a keyword. In this case use grep

cut -f2 -d= yeet.d | grep just

This extracts all lines containing the word just.

flappix
  • 2,038
  • 17
  • 28