5

I need to extract the characters before last colon : and also remove the square brackets [] in the last line. My file structure is

256.XXX.XXX.X:20234
214.XXX.XXX.X:7249
[2200:XXXX:XXXX:XXX:XXXX:XXXX:XXXX:XXXX]:46288

I need output file as in the form of:

256.XXX.XXX.X
214.XXX.XXX.X
2200:XXXX:XXXX:XXX:XXXX:XXXX:XXXX:XXXX
ilkkachu
  • 133,243
  • 15
  • 236
  • 397
Nani
  • 343
  • 3
  • 5
  • 13

5 Answers5

10

Remove everything after the last colon, and then any brackets left anywhere:

sed 's/:[^:]*$//; s/[][]//g'

Or

sed 's/\(.*\):.*/\1/; s/[][]//g'

(here using the fact that the first .* will be greedy and swallow as many :s as possible).

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
3

This will extract all characters before last 'colon' and remove the brackets [ ] as the example you give.

rev <yourfile.txt | cut -d: -f2- | rev | tr -d '[]'

Replace yourfile.txt by your file name or remove the word <yourfile.txt to read the standard output.

Luciano Andress Martini
  • 6,490
  • 4
  • 26
  • 56
2

awk -F: '{OFS=":"; NF--; print $0}' $file

or

cat file | awk -F: '{OFS=":"; NF--; print $0}'

which breaks down as:

  • -F: set the input field separator to :
  • OFS=":" set the output field separator to :
  • NF-- reduce the Number of Fields by 1 (get rid of the last field)
  • print $0 print the remaining records, separated by the OFS (:) character.

Update to also remove the square brackets:

awk -F: '{OFS=":"; NF--; gsub(/\[|\]/, ""); print $0}' $file

  • added gsub(/\[|\]/, "")1 which performs a global substitution on the square brackets, replacing them with nothing, and returning the substituted string.
Tim Kennedy
  • 19,369
  • 4
  • 38
  • 58
2

Shell only:

while IFS= read -r line; do
    tmp=${line%:*}               # remove last colon and following chars
    tmp=${tmp#"["}               # remove leading open bracket
    result=${tmp%"]"}            # remove trailing close bracket
    printf "%s\n" "$result"
done < file
glenn jackman
  • 84,176
  • 15
  • 116
  • 168
  • I don't know why but I always love this kind of solutions... Just because it does run with a minimal tools environment. – Luciano Andress Martini May 13 '19 at 15:19
  • And [I always cringe at them](/q/169716). Here, you can also add a portability dimension as those `${tmp#[}` won't work with ksh93 or zsh. – Stéphane Chazelas May 13 '19 at 15:28
  • @StéphaneChazelas In true I agree with you in security / reliability terms. But I think you understand my point of view too. – Luciano Andress Martini May 13 '19 at 15:30
  • 1
    Seems to work fine with ksh "version sh (AT&T Research) 93u+ 2012-08-01". I don't have an older version to test with. – glenn jackman May 13 '19 at 15:44
  • 1
    `ksh -c 'tmp=${tmp#[}'` gives a syntax error with ksh93u+, but `tmp=anything ksh -c 'tmp=${tmp#[}'` doesn't. Looks like a bug. In any case, `[` being a wildcard operator is better quoted. `tmp=${tmp#"["}` works OK in any POSIX-like shell. You'd want to replace `echo` with `printf '%s\n'` as well. – Stéphane Chazelas May 13 '19 at 19:00
0

Command:

awk -F ":" 'OFS=":"{$NF="";print $0}' filename | sed "s/:$//g"| sed "s/^\[//g"|sed "s/\]//g"

output

256.XXX.XXX.X
214.XXX.XXX.X
2200:XXXX:XXXX:XXX:XXXX:XXXX:XXXX:XXXX
Praveen Kumar BS
  • 5,139
  • 2
  • 9
  • 14
  • 1
    This doesn’t seem any better than Tim Kennedy’s existing answer. For future reference, if you’re using AWK, you don’t need `sed` too... – Stephen Kitt May 15 '19 at 16:38