Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign variable to cut -f field

Tags:

sh

awk

cat

Using cut, I want to know how to use it as:

awk -v id=3 -v RS= -F '::'  '($1==id) {print $3}' jenny  | a=1 ;cut -d$'\n' -f$a

I want to use it in a loop where i is replaced with, e.g., -f 1...3


Input

0::chkconfig --list autofs::
 autofs                 0:off   1:off   2:on    3:on    4:on    5:on    6:off

1::grep "^PROMPT=" /etc/sysconfig/init::
 PROMPT=yes

2::rpm -q prelink::
 prelink-0.4.0-2.el5

3::if [ -z "$(grep -l "hard core" /etc/security/limits.conf /etc/security/limits.d/*)" ]; then echo "empty"; else echo -e "$(grep -l "hard core" /etc/security/limits.conf /etc/security/limits.d/*)"; fi::
 /etc/security/limits.conf
/etc/security/limits.d/test

4::sysctl fs.suid_dumpable::
 fs.suid_dumpable = 0

5::stat /etc/motd::
   File: `/etc/motd'
  Size: 17              Blocks: 16         IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 10125343    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-04-09 07:56:19.000000000 +0500
Modify: 2019-03-30 19:22:13.000000000 +0500
Change: 2019-03-30 19:22:13.000000000 +0500

Expected Output

 /etc/security/limits.conf
    /etc/security/limits.d/test

As field 1 and field currently it's all coming in $3. I tried separating with newline in awk; it doesn't seem to catch.

like image 423
lazereyes Avatar asked Dec 28 '25 08:12

lazereyes


2 Answers

To get your desired output from the given input, try:

$ awk '/^$/{f=0} f{print} /3::/{f=1}' file
 /etc/security/limits.conf
/etc/security/limits.d/test

To get only one output line as selected with a variable i:

$ awk -v i=1 '/3::/{n=NR+i} n==NR' file
 /etc/security/limits.conf
$ awk -v i=2 '/3::/{n=NR+i} n==NR' file
/etc/security/limits.d/test

The awk variable i can, of course, be set to the value of a shell variable i:

$ i=2
$ awk -v i="$i" '/3::/{n=NR+i} n==NR' file
/etc/security/limits.d/test

The stanza can also be selected from a variable:

$ i=2
$ k=3
$ awk -v i="$i" -v k="$k" -F:: '$1==k{n=NR+i} n==NR' file
/etc/security/limits.d/test

How it works:

  • -v i="$i" -v k="$k"

    These options set awk variable i and k to the values of the shell variables $i and $k, respectively.

  • -F::

    This sets the field separator to ::.

  • $1==k {n=NR+i}

    If the first field of the current line equals the variable k, then set variable n to the current line number, NR, plus i.

  • n==NR

    If the current line number, NR, is n, then print this line.

like image 154
John1024 Avatar answered Dec 31 '25 00:12

John1024


With sed:

$ id=3; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny 
 /etc/security/limits.conf
/etc/security/limits.d/test

Explanations:

  • Your shell will interpret the command and replace id by its value.
  • /^$id::/,/^$/{} the scope {} will be executed only between the lines that starts with the value of id followed by :: (/^$id::/) until an empty line (/^$/)
  • /^[[:blank:]]*\//p for the lines that start with some POSIX blank character class (e.g. space/tab) followed by / print the line. This will print your two paths.

To specify a line:

$ id=3; line=1; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | cut -d$'\n' -f"$line"
 /etc/security/limits.conf
$ id=3; line=2; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | cut -d$'\n' -f"$line"
/etc/security/limits.d/test
$ id=3; line=1; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | sed -n "${line}p"
 /etc/security/limits.conf
$ id=3; line=2; sed -En "/^$id::/,/^$/{/^[[:blank:]]*\//p}" jenny | sed -n "${line}p"
/etc/security/limits.d/test
like image 31
Allan Avatar answered Dec 30 '25 23:12

Allan