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


I need output file as in the form of:

  • In your output, you also remove the [ ], but you don't mention it
    – Philippos
    May 13 '19 at 15:06
  • Ok I edited my answer to remove brackets... May 13 '19 at 15:10
  • Is that netstat result which contains IP and port?
    – Ivan Chau
    May 14 '19 at 6:15

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

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


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

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

  • 1
    The [ ] also need to be removed, it seems
    – Philippos
    May 13 '19 at 15:05
  • @Philippos, OK, I'm with you now. Thanks. I've edited it in. May 13 '19 at 15:09
  • Thanks everyone. This is working
    – Nani
    May 13 '19 at 15:14
  • 1
    [][] is something of a regex corner-case and might warrant some explaining. May 14 '19 at 0:41

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.

  • 1
    Note that rev is not a standard (POSIX) command (comes from plan9, GNU has one as well). That unquoted [] will cause an error in csh or zsh. May 13 '19 at 15:17
  • Right I corrected it with quotes. In practice there are some unixes without rev or even some busybox environment that does not have it? May 13 '19 at 15:25
  • 2
    There's none on Solaris. BSDs, GNU, busybox, AIX and HPUX seem to all have one. May 13 '19 at 15:26
  • Thank you for the information! May 13 '19 at 15:26

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
  • I don't know why but I always love this kind of solutions... Just because it does run with a minimal tools environment. May 13 '19 at 15:19
  • And I always cringe at them. Here, you can also add a portability dimension as those ${tmp#[} won't work with ksh93 or zsh. 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. 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. 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. May 13 '19 at 19:00

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


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.


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


  • 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... May 15 '19 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.