5

I'm working with large variables and to speedup my script I'd like to awk or grep a variable without using echo/printf

what I've tried:

awk "/test/ {for(i=1; i<=100; i++) {getline; print}}" "$var"
awk: fatal: cannot open file `<<$var content>>' for reading (No such file or directory)

grep -A 100 test "$var"
grep: `<<$var content>>': No such file or directory
Orlo
  • 828
  • 2
  • 11
  • 28

2 Answers2

8

In bash you can redirect from a variable to stdin using the one-line heredoc:

awk "/test/ {for(i=1; i<=100; i++) {getline; print}}" <<< "$var"
Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
  • 1
    I do not think you should remove the quotes. `<<< "$var"` – Jotne Feb 02 '14 at 14:48
  • @Jotne AFAIK the heredoc body is treated as a string: interpolation will be performed, but shell injection (like with `var="a; rm -rf `") will not work. Anyway, a pair of `""` does not hurt, so I added them. – Stefano Sanfilippo Feb 02 '14 at 14:53
  • 2
    Without the double quotes, you get a single line of input — the newlines in the input are flattened into spaces (and multiple spaces are flattened into single spaces, etc). From the question, it appears that `$var` might have more than 100 lines after the line containing `test` — so the double quotes are necessary. – Jonathan Leffler Feb 02 '14 at 14:58
2

If I understand you, you have a multi-line string stored in the shell variable var and you'd like to print 100 lines from the line containing test in that string inclusive. With GNU awk that'd be:

$ awk -v var="$var" 'BEGIN{ printf "%s", gensub(/.*(test([^\n]*\n){100}).*/,"\\1","",var) }'

e.g. to print "test" plus the 2 or 3 lines after it, inclusive:

$ echo "$var"
abc
def
test
ghi
klm
nop

$ awk -v var="$var" 'BEGIN{ printf "%s", gensub(/.*(test([^\n]*\n){2}).*/,"\\1","",var) }'
test
ghi

$ awk -v var="$var" 'BEGIN{ printf "%s", gensub(/.*(test([^\n]*\n){3}).*/,"\\1","",var) }'
test
ghi
klm

With other awks you can use match() + substr() to get the same result.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • I'm getting `/usr/bin/awk: Argument list too long` – Orlo Feb 02 '14 at 22:20
  • Then you are not using the script I posted as `awk` has zero args in my script. Note that on Solaris /usr/bin/awkis old, broken awk which should never be used. If you're on Solaris use /usr/xpg4/bin/awk or nawk. – Ed Morton Feb 03 '14 at 14:53