6

I write the follwoing awk script:

% echo /var/sysconfig/network/my_functions  alpha beta gama  | \
      awk -v word=alpha '$2  == word { print $0 }'

how to tell awk that I want to print all line except $1 (/var/sysconfig/network/my_functions PATH ) so I will get the following:

alpha beta gama

instead of

/var/sysconfig/network/my_functions alpha beta gama

remark: line content can be anything and not limit by strings/word quantity

akira
  • 62,099
jennifer
  • 1,117

8 Answers8

6

If you set $1 to "" you will leave the delimiting space. If you don't want to do that you have to iterate over the fields:

awk '{for (f=2; f<=NF; ++f) { if (f!=2) {printf("%s",OFS);} printf("%s",$f)}; printf "\n" }'

Edit: fixed per Gilles' comment.

Another way to do the same thing:

awk '{d = ""; for (f=2; f<=NF; ++f) {printf("%s%s", d, $f); d = OFS}; printf("\n") }'
2

Somehow I think this would be so much easier and more intuitive to do with the cut command:

echo /var/sysconfig/network/my_functions  alpha beta gama | cut -d' ' -f 2-

The only problem is that cut doesn't support multiple different types of whitespace at once for delimiters. So if you have spaces or tabs, it won't work.

deltaray
  • 1,997
1

This (somewhat complicated) solution, which is somewhat similar to Gilles’s answer,

  • outputs no space at the beginning of the line,
  • correctly handles the case where the input line begins with whitespace, and
  • preserves inter-field whitespace.
awk -v word=alpha '
    $2 == word {
        i = index($0, $1)               # Find $1 within $0 (the line).
        if (i > 0) {                    # Sanity check; should always be true.
                i = i + length($1)      # Find space after $1.
                temp = substr($0, i)
                i = index(temp, $2)     # Find $2 in remainder of line.
                if (i > 0) {            # Sanity check; should always be true.
                        print substr(temp, i)
                }
        }
    }'

I believe the in-line comments explain it fairly well.  We find $1’s position in the line (remember, I’m explicitly not assuming that it’s at the beginning).  Then, à la Gilles’s answer, we strip $1 (and the whitespace before it, if any) off the line.  Then find $2’s position in the remainder of the line, and strip off the whitespace before that.


Here is a slight streamlining of Dennis Williamson’s answer.

awk -v word=alpha '$2==word { for (f=2; f<=NF; ++f) printf("%s%s", $f, (f==NF?ORS:OFS)) }'

Like Dennis’s answer, it outputs the fields $2, $3, …, $NF (omitting $1) with default separation.  Dennis took the approaching of preceding $3, …, $NF (but not $2) with the default output field separator.  I took the approach of following $2, $3, …, $(NF-1) (but not $NF) with the OFS.  And, since $NF is followed by the output record separator (ORS), we can use a ?: operator with no null terms, and eliminate the final printf("\n").

1
 % echo /var/sysconfig/network/my_functions  alpha beta gama | \
      awk -v word=alpha \
             '$2 == word { $1=""; print $0 }'
akira
  • 62,099
  • 2
    With the caveat already observerd by Dennis that this leaves the whitespace before $2. – Gilles 'SO- stop being evil' Nov 21 '10 at 16:12
  • (Some necromancy here, but this thread popped up among the active questions just now): The extra whitespace can be trimmed with e.g. cut as in awk -v word=alpha '$2==word {$1=""; print}' | cut -b2- (if the poster doesn't want to use cut directly as in deltaray's answer, but that lacks the selection on "$2" part (which could be fixed with grep instead of awk)). – Daniel Andersson Apr 19 '12 at 11:55
1

I think in awk there's no way but to remove the first field manually. (There are other ways if you're willing to normalize the inter-field space.)

awk '$2 == word {match($0, "("FS")+"); print substr($0, RSTART+RLENGTH);}'
  • Note that, if there is whitespace before $1, this solution will strip off that leading whitespace and leave all the fields (including $1). Not that there’s any suggestion in the question that that might happen. – Scott - Слава Україні Jan 16 '17 at 04:43
0

echo alpha beta gama | awk '{$1="";print}'

beta gama

Alex
  • 1
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. – Community Feb 15 '23 at 16:37
-1

Use this if you want to change the delimiter. My delimiter is "|":

awk -F '|' '{d = ""; for (f=2; f<=NF; ++f) {printf("%s%s", d, $f); d = OFS}; printf("\n") }'
MJH
  • 1,155
  • 1
    (1) This is a minor variation on Dennis Williamson’s answer.  If you copy somebody else’s answer, even to improve on it, you should give credit to the source.  (2) I believe that this doesn’t really contribute enough new information to justify a separate answer.  Things like this should probably be comments.  Once you have sufficient reputation you will be able to comment on any post.  … (Cont’d) – Scott - Слава Україні Jan 16 '17 at 04:41
  • (Cont’d) …  I do realize you don’t have the reputation to do that, so earn it, and then do that. (3) Setting the field separator is often useful, but is not really relevant to this question.  In particular, your answer is incomplete since it doesn’t set the output field separator to match the input field separator, so your command will never produce the input line with the first field removed. – Scott - Слава Україні Jan 16 '17 at 04:42
  • Thanks for correction, I am just learning shell scripting so I don't mind giving credit to Dennis :), anyways Thanks for correcting me - whoever is managing this can delete my post if this is redundant and of no help to others. Thanks and Good Luck !! – Dhaulakhandi Mar 25 '17 at 10:11
  • I appreciate everyone who is posting in stackover flow as this has helped many times throughout my career :), Thanks to the inventor and people who participate. – Dhaulakhandi Mar 25 '17 at 10:13
-1

Everyone always makes it harder than it is

$ echo /var/sysconfig/network/my_functions alpha beta gama |
awk -v word=alpha '$2==word{print substr($0,index($0,$2))}'
alpha beta gama