0

I was wondering if it's possible to use the grep command to pick out a string that contains spaces and line breaks, e.g.:

Hello
I
am
here right now

I'm still very new to regexps and using the command line in general (this is my second day of learning this), so my attempt was this:

grep H[\s\S]*w <filename>

I thought that [\s\S] would give you any character, including spaces and line breaks (unlike .), but it didn't work.

I use the terminal on my Mac OS (not sure if that makes a difference).

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

2 Answers2

1

grep works on lines, so, "you can't do that"; but, when I need to do something like that on bash, and I don't want to/can't use perl or alike (or, honestly, I just want to use grep) I do something like this:

tr '\n' '\a' < <filename> | grep --only-matching Hello$'\a'I$'\a'am$'\a'here\ right\ now | tr '\a' '\n'

tr translates chars; here, you are 'translating' new lines to bell ascii char [hex code \x07 or '\a'], then process that on grep (note that grep sees a long one line string, with bell ascii chars instead of new line chars), and then, back to 'normal', translating bell ascii chars to newline.

there is no need to use bell ascii char: you can use any char that doesn't appear in your file; in my case, it's just that I like the number seven and, usually, a text file doesn't contain any bell ascii chars

BTW: the $'\a' is Bash ANSI-C Quoting

  • Thanks for your help! Is it possible to generalise this command to other strings than this specific one? E.g. all strings that start with 'hello' and end with 'now'? – Dominique May 10 '18 at 18:45
  • The reason I ask is because I unsuccessfully tried it with:

    'tr '\n' '\a' < | grep Hello.*here | tr '\a' '\n''

    (It still gives me the full text, not just the part up to 'here').

    – Dominique May 10 '18 at 18:52
  • It is perfectly possible, and your try is correct; you just only forgot the --only-matching flag in your grep command; by default, grep print all matching lines (the full line): here, when you do tr '\n' '\a' < <filename>, you are sending the one-line version of your file to grep, so, from grep's perspective, the file has one big line, thus, any match will print the full big line, i.e., your entire file. With the --only-matching flag, your are saying to grep: hey, don't print the full matching line, just the matching chars – alsjflalasjf.dev May 10 '18 at 19:58
  • You're welcome; consider to mark my answer as the one resolved your question – alsjflalasjf.dev May 12 '18 at 08:43
  • Of course, done :) – Dominique May 13 '18 at 09:42
0

Try this:

sed -e '1h;2,$H;$!d;g' -re 's/(.*)(H\w+\n)(.*w\n)(.*)/\2\3/' test.txt

With a test.txt file containing:

Something 
Hello
I
am
here right now
Something else

Tested with sed (GNU sed) 4.4. You can install GNU sed on macOS via Homebrew Default sed on macOS is BSD sed, some options are slightly different.

Cheers,

Nibor Ndj
  • 101