Skip first match in file using Bash

grep
awk
sed
grep ignore first match
bash skip first lines of file
sed command
grep regex
bash skip first n lines of file

I have this file contains this kind of data

NAME: "Chassis", DESCR: "Nexus5020 Chassis"
PID: N5K-C5020P-BF     , VID: V04 , SN: SS613390FZT

NAME: "Module 1", DESCR: "40x10GE/Supervisor"
PID: N5K-C5020P-BF     , VID: V04 , SN: JA91344BHNK

NAME: "Module 2", DESCR: "6x10GE Ethernet Module"
PID: N5K-M1600         , VID: V01 , SN: JA71228018M

NAME: "Module 3", DESCR: "8x1/2/4G FC Module"
PID: N5K-M1008         , VID: V01 , SN: JAB1531020C

By using shell script, I managed to grab relevant data which are string in DESCR: and SN: and save it in csv file as below;

Nexus5020 Chassis,SS613390FZT
40x10GE/Supervisor,JA91344BHNK
6x10GE Ethernet Module,JA71228018M
8x1/2/4G FC Module,JAB1531020C

My question is what modification needed so the script will skip the first match for DESCR: and SN: so it will turn out like this in the output?

40x10GE/Supervisor,JA91344BHNK
6x10GE Ethernet Module,JA71228018M
8x1/2/4G FC Module,JAB1531020C

The script is here :

#/bin/bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'

while read -r; do
        if [[ $REPLY =~ $re_descr ]]; then
                descr=${BASH_REMATCH[1]}
                continue
        fi
        if [[ $REPLY =~ $re_sn ]]; then
                sn=${BASH_REMATCH[1]}
        fi
        if [[ $descr && $sn ]]; then
                printf '%s\t%s\n' "$descr","$sn"
                unset -v descr sn
        fi
done < <(cat <filename>)

You can add a variable firstline (init it as true). When you have sn and descr matched, set the var to false, else print.

EDIT: Alternative.

You can use tr and sed for manipulting the file. First make sure that all lines (except the first) start with DESCR:

tr -d "\n" < file | sed 's/DESCR/\n&/g; $ s/$/\n/'

The first line is without DESCR, the second one is the one you want to ignore. So process this stream from the third line:

tr -d "\n" < file | sed 's/DESCR/\n&/g; $ s/$/\n/' |
   sed -rn '3,$ s/DESCR: "([^"]+).*SN: ([^[:space:]]+).*/\1,\2/p' 

grep -v: How to exclude only the first (or last) N lines that match , You can put this code into your .bashrc (or config of your shell, if it is other): Remove first occurrence cat file | dtrash 'stuff' # Remove four (e.g. print only the line number for each match via tools like sed / awk , then tail  Replace the first match in a file with new text; Replace the last match in a file with new text; Escaping backslash in replace commands to manage search and replace of file paths; Replace all files full path with just the filename no directory; Substitute text but only if some other text is found in the string

You can replace done < <(cat <filename>) by done < <filename> | sed 1d.

It looks like this (with /tmp/foo as input file):

#/bin/bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'

while read -r; do
        if [[ $REPLY =~ $re_descr ]]; then
                descr=${BASH_REMATCH[1]}
                continue
        fi
        if [[ $REPLY =~ $re_sn ]]; then
                sn=${BASH_REMATCH[1]}
        fi
        if [[ $descr && $sn ]]; then
                printf '%s\t%s\n' "$descr","$sn"
                unset -v descr sn
        fi
done < /tmp/foo | sed 1d

awk / cut: Skip First Two Fields and Print the Rest of Line, I want my input file with the following output: a test more than we take. How do I printing lines from the nth field using awk under UNIX or Linux  We can then use that patch file with patch to have those differences applied to the files in the working folder with a single command. The options we’re going to use with diff are the -u (unified context) option we have used earlier, the -r (recursive) option to make diff look into any sub-directories and the -N (new file) option.

Instead of passing the input to while loop from the end, pass the input as inner loop.

Try this to remove the first line for multiple input files

$ cat in.txt
line1
line2
line3
line4
$ perl -ne ' { print if $.>1 ; close(ARGV) if eof } ' in.txt in.txt | while read -r a ; do ; echo $a  ; done
line2
line3
line4
line2
line3
line4
$

I just used in.txt in.txt to show that it removes the first line..

Sed - An Introduction and Tutorial by Bruce Barnett, This is the Grymoire's UNIX/Linux SED editor. How to use sed, a special editor for modifying files automatically. The first match for '[0-9]*' is the first character on the line, as this matches zero or more numbers. you must expand the regular expression to match the rest of the line and explicitly exclude  The greedy behaviour of a sed substitution command will by default substitute first match occurrence on every line. For example: $ cat text bash bash bash bash bash bash bash bash bash $ sed 's/bash/sed/' text sed bash bash sed bash bash sed bash bash

Linux grep command help and examples, Linux grep command help, examples, and additional information. files using a wildcard. Notice that each line starts with the specific file where that match occurs​. -i, --ignore-case, Ignore case distinctions in both the PATTERN and the input files. -v, --invert- The scanning will stop on the first match. Grep is a Linux / Unix command-line tool used to search for a string of characters in a specified file. The text search pattern is called a regular expression. When it finds a match, it prints the line with the result.

grep(1) - Linux manual page, Typically PATTERNS should be quoted when grep is used in a shell command. -T, --initial-tab Make sure that the first character of actual line content lies on a --exclude=GLOB Skip any command-line file with a name suffix that matches  How to Negate a Set of Characters in Linux. 10. You can as well negate a set of characters using the ! symbol. The following command lists all filenames starting with users-i, followed by a number, any valid file naming character apart from a number, then a lower or upper case letter and ends with one or more occurrences of any character.

Sed One-Liners Explained, Part II: Selective Printing of Certain Lines, It was supposed to print first 10 lines of a file, but it seems that it just printed only the first 9. Upon quitting with "q" command, sed actually prints the contents of pattern space Print only the lines that match a regular expression (emulates "​grep"). As it starts executing at line 3, the effect is - print line 3, skip 6, print line 10,  find can generate a list of these files using the following command: find -name "data?.txt" This command uses the question mark wildcard to match any file that has a single character after the word "data" in its name, ending in the extension ".txt". It produces the following output:./data1.txt ./data3.txt ./data2.txt

Comments
  • If you've the result in a .csv file, and need to skip the first match, this might do: awk 'NR>1 {print $0}' csv_file
  • Thanks. I know that. But direct modification to the script is needed because it will cleanup multiple files which resulted in one csv file. If I use awk command to the file, result won't be the same since it has been processed earlier.
  • Simple answer: change < <(cat <filename>) to < <(tail -n+3 <filename>) Note: your use of cat is an Unnecessary Use Of cat (a UUOc). Never use process substitution to cat a file to feed a while loop. Simply while read -r; do ... done <filename.
  • Just tried. It didn't work with multiple source file.
  • No, I would wrap this within a simple for loop to read several input files like this.