shoham
shoham

Reputation: 812

script to print lines with 4 words

I'm starting out with sed, I need to run over the lines of a file, print the lines with exactly 4 words, and in those lines I should print the first word 3 times.

What i mean is, if this file is given:

Hello hi 123
if a equals b
you
one abc two three four
dany uri four 123

This is the output:

if if if a equals b
dany dany dany uri four 123

This is what I did:

sed `s/\(\<.\+\>\)\(\<.\+\>\)\{3\}/\1/` F1

where F1 is an existing file. I was told to put all the \ in so the bash interpreter won't touch it. Here's the script without them:

sed 's/(<.+>)(<.+>){3}/\1' F1

the error is:

./P8.1: line 1: s/(<.+>)(<.+>){3}/1/: No such file or directory sed: -e expression #1, char 1: unknown command: `F'

What's wrong and how do I fix it?

Thanks.

Upvotes: 0

Views: 283

Answers (3)

potong
potong

Reputation: 58483

This might work for you (GNU sed):

sed -nr '/^(\S+)(\s\S+){3}$/s//\1 \1 &/p' file

Upvotes: 0

janos
janos

Reputation: 124714

You can do like this:

sed -ne 's/^\(\w\+\)\(\W\+\w\+\)\{3\}$/\1 \1 &/p' 

If you are using GNU sed, then it's more readable using the -r flag like this:

sed -nre 's/^(\w+)(\W+\w+){3}$/\1 \1 &/p'

Explanation:

  • Use the -n flag to not print lines by default, only by explicit p command in sed
  • \w is a word character, \W is a non-word character
  • \1 is the matched captured by the first \(...\)
  • & is the entire matched pattern. Since we're matching ^...$ this is the entire original line
  • With the -r in GNU sed (-E in BSD sed), we can simplify \(....\) as (...) and \+ as + and \{...\} as {...}

I'm not sure if \w and \W will work in all systems. If it doesn't work, you can use something like [a-zA-Z0-9_] instead of \w and [^a-zA-Z0-9_] instead of \W.

Upvotes: 2

Akshay Hegde
Akshay Hegde

Reputation: 16997

An Awk Approach you may try

$ cat file      
Hello hi 123
if a equals b
you
one abc two three four
dany uri four 123

Awk examples

$ awk 'NF==4{print $1,$1,$0}' file
if if if a equals b
dany dany dany uri four 123

OR

$ awk '{f = NF == 4 ? 1 : 0; $0 = $1 FS $1 FS $0}f' file
if if if a equals b
dany dany dany uri four 123

Upvotes: 2

Related Questions