2

I have a file like below:

chs_de_le_q1gg
fd_tr_mn_0
fd_tr_mn_06
fd_tr_mn_070
fd_tr_mn_0716
fd_tr_mn_09013
fd_tr_mn_092433
fd_tr_mn_1020333
fd_tr_mn_12013332
dsdas_1
dsdas_12
dsdas_212
sdasd_4567
weqwe_32323
dasds_232322
2321321_rewrwe_3233
32_Ff
asdasd_1_fff

I need to remove the lines ending with digits ranging from 4-8 of length; also to remove lines starting from numbers.

the below works to match the lines which I want to delete, but then doing invert match on that match with adding -iv doesn't work.

cat test.txt | grep -oP '(?<![0-9])[0-9]{4,8}(?![0-9])'
1
  • Since you only want to delete lines of up to 8 digits at the end, you should include lines with more than 8 digits at the end in your example so we could test that a potential solution actually works. Also, add the expected output for your posted sample input.
    – Ed Morton
    Oct 7, 2022 at 12:34

3 Answers 3

1

To remove lines which:

  • starts with a digit: ^[0-9] or ^\d

  • or ends with 4~8 character length of digits: [0-9]{4,8}$ or \d{4,8}$.

    grep -vE '^[0-9]|[0-9]{4,8}$'  infile >output
    sed -E '/^[0-9]|[0-9]{4,8}$/d' infile >output
    grep -vP '^\d|\d{4,8}$' infile        >output
    

To remove lines which:

  • starts with a digit: ^[0-9]

  • or ends with exactly 4~8 character length of digits: [^0-9][0-9]{4,8}$ or \D\d{4,8}$.

    grep -vE '^[0-9]|[^0-9][0-9]{4,8}$'  infile >output
    sed -E '/^[0-9]|[^0-9][0-9]{4,8}$/d' infile >output
    grep -vP '^\d|\D\d{4,8}$' infile            >output
    
5
  • thank you so much.. one more doubt, in case if we want to ignore 1-2 & 4-8 digits ending at last. then ?
    – rose
    Oct 7, 2022 at 6:25
  • @rose that's ([0-9]{4,8}|[0-9]{1,2})$ Oct 7, 2022 at 8:12
  • @rose FYI that's a question, not a doubt. A doubt means you don't believe something, a question just means you want to know about something. If you don't think a solution will work then you have a doubt about it, if you want to know how to extend a solution then you have a question about it. See english.stackexchange.com/q/2429 for one discussion on the topic.
    – Ed Morton
    Oct 7, 2022 at 12:40
  • how to include multiple grep in this, incase if i want to exclude _ff in the same query ?
    – rose
    Nov 2, 2022 at 16:58
  • @rose grep -vE 'exclude1|exclude2|exclude3|...|excludeN', exclude# is an expression that you wish to exclude lines with that conditions. so for _ff you will need grep -v '_ff' to exclude lines that contains the string _ff everywhere in the line; you can add end of line $ or start of line ^ anchors per your need. if you have a new question please ask it separately. Nov 3, 2022 at 5:26
0

Using any POSIX awk:

$ awk '!( /^[0-9]/ || /(^|[^0-9])[0-9]{4,8}$/ )' file
chs_de_le_q1gg
fd_tr_mn_0
fd_tr_mn_06
fd_tr_mn_070
dsdas_1
dsdas_12
dsdas_212
asdasd_1_fff
0

Using Raku (formerly known as Perl_6)

Below deletes lines starting with a digit, or containing runs of 4-to-8 digits adjacent to the line ending (unless is synonymous with if not):

raku -ne '.put unless /^ \d | \d ** 4..8 $ /;'  

Sample Input:

chs_de_le_q1gg
fd_tr_mn_0
fd_tr_mn_06
fd_tr_mn_070
fd_tr_mn_0716
fd_tr_mn_09013
fd_tr_mn_092433
fd_tr_mn_1020333
fd_tr_mn_12013332
dsdas_1
dsdas_12
dsdas_212
sdasd_4567
weqwe_32323
dasds_232322
2321321_rewrwe_3233
32_Ff
asdasd_1_fff

Sample Output:

chs_de_le_q1gg
fd_tr_mn_0
fd_tr_mn_06
fd_tr_mn_070
dsdas_1
dsdas_12
dsdas_212
asdasd_1_fff

Note: Above would delete a line such as fd_tr_mn_123456789, since 8-digits are adjacent to the $ end-of-line. If the OP desires to retain runs of digits greater-than 8-digits adjacent to the line ending, the following regex works:

raku -ne '.put unless /^ \d | \D\d ** 4..8 $ /;' 

Above, a line such as fd_tr_mn_123456789 would be retained in the return.

https://raku.org

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .