sed -n 's/.*tex:/[preventColonFromResult]/p' ./BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?


  • input is ./BitTorrentSync/Gyn/1.12.2015.tex: Agents in young <40yr?.
  • expected output is ./BitTorrentSync/Gyn/1.12.2015.tex.

I think -n does not make sense here because I want to pass the output to less. I search the match .*tex: but it actually should not include : in the result. I keep p at end to not do replacement.

DonCristi's output for grep

Trying to split at colon : with grep without the seed of sed/grep/... Code in GNU Grep 2.23

find . -name "*.tex" -exec ggrep -i -oP '^[^:]*(?=:)' {} \; | less

Unsuccessful output with output as the content of files, not filenames. This command actually includes only content of files, and it leaves outside the filenames.

How can you get everything before colon : in SED/Grep/...?

  • 1
    I feel that this is grep's output. There are better solutions with just grep.
    – Braiam
    Commented Apr 19, 2016 at 14:08
  • I cannot answer if I'm not sure. Is this grep output or not?
    – Braiam
    Commented Apr 19, 2016 at 14:45
  • @Braiam Yes, it is. Particularly find . -name "*.tex" -exec grep -i -H "agent" {} \; . Commented Apr 19, 2016 at 14:46
  • @don_crissti Can you get it work with the find command? Please, provide your output. My output in unsuccessful and many lines of ggrep: agent: No such file or directory. Commented Apr 20, 2016 at 11:17
  • @don_crissti Your command leaves filenames outside and includes filecontents. Expected output is filename without colon. Commented Apr 20, 2016 at 16:38

5 Answers 5

  1. sed operates on stdin, not on its arguments, unless you are giving it filenames.
  2. It's easier to specify what you want to remove than what you want to keep, with sed.

Instead of

sed -n 's/.*tex:/[preventColonFromResult]/p' ./BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?

perhaps you meant

printf '%s\n' './BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?' | sed 's/:.*//'

But for this specific use case, you may as well just use a single-purpose tool, namely cut:

printf '%s\n' './BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?' | cut -d: -f1

If you would have taken the time and read the grep manual, you would have found the l option

-l, --files-with-matches
       Suppress normal output; instead print the name of each input file from which  output would normally
       have been printed. The scanning will stop on the first match.

Your find command would look like

find . -name "*.tex" -exec grep -il "agent" {} \; | less

or faster

find . -name "*.tex" -exec grep -il "agent" {} + | less

If you are set on doing this in sed and matching on the tex: instead of just :, you can also try:

echo "./BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?" | sed 's/\(^.*tex\):.*/\1/'
echo "bla-bla-bla:ololo-testo" |sed 's/:.*$//'  
  • 2
    the $ anchor in that sed statement isn't necessary -- * is greedy by default
    – Jeff Schaller
    Commented Apr 19, 2016 at 10:54
  • 1
    @JeffSchaller, it makes a difference on inputs that contain invalid characters (which . won't match). Commented Apr 19, 2016 at 11:11
  • 1
    I had to go look at pubs.opengroup.org/onlinepubs/9699919799/basedefs/… to see what I missed. "A <period> ( '.' ), when used outside a bracket expression, is a BRE that shall match any character in the supported character set except NUL." Is there an odd locale case to worry about?
    – Jeff Schaller
    Commented Apr 19, 2016 at 11:24
  • 3
    In UTF-8 locales (the norm nowadays), . generally won't match characters in single-byte character sets whose value is above 127. é in UTF-8 is c3 a9, while it's e9 in iso8859-1 (the most common western charset before utf-8 became popular). So if you have Stéphane written in the iso8859-1 character set and the current locale's charset is UTF-8, . won't match that 0xe9 byte in between the t and p as that doesn't form a valid character in UTF-8. So s/:.*$// on an input like foo:St<0xe9>phane:C will yield foo:St<0xe9>phane:C while s/:.*// will yield foo<0xe9>phane:C. Commented Apr 19, 2016 at 11:46
  • 2
    (that's something that you can generally ignore when the input is valid text, but worth mentioning once in a while). Commented Apr 19, 2016 at 11:48
$ abc="./BitTorrentSync/Gyn/1.12.2015.tex:  Agents in young <40yr?"
$ pqr=$(echo "$abc" | sed -e 's/:.*//')
$ echo $pqr

This works for me.

  • What is the value of abc?
    – Anthon
    Commented Apr 19, 2016 at 9:40
  • I gave it a random string aabbccddee:123123abc to test it.
    – sudhansh_
    Commented Apr 19, 2016 at 9:42
  • Tried it with the sample that the OP gave. It worked with that too. 'abc="./BitTorrentSync/Gyn/1.12.2015.tex: Agents in young <40yr?"'
    – sudhansh_
    Commented Apr 19, 2016 at 9:46
  • 1
    Please update your answer with such a random string , and with the actual output, that would make it IMO more complete and understandable.
    – Anthon
    Commented Apr 19, 2016 at 10:19

You must log in to answer this question.

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