3

I have a file that has several lines of which one line is

-xxxxxxxx()xxxxxxxx

I want to add the contents of this line to a new file

I did this :

awk ' /^-/ {system("echo" $0 ">" "newline.txt")} '

but this does not work , it returns an error that says :

Unnexpected token '(' 

I believe this is due to the () present in the line. How to overcome this issue?

Allan
  • 12,117
  • 3
  • 27
  • 51
Deeraj Theepshi
  • 183
  • 3
  • 10
  • Not clear, please be more clear in your post's question. Add samples of Input and sample of output in your post in CODE TAGS `{}` button and let us know then. – RavinderSingh13 May 16 '18 at 08:44

3 Answers3

3

You need to add proper spaces!

With your erronous awk ' /^-/ {system("echo" $0 ">" "newline.txt")} ', the shell command is essentially echo-xxxxxxxx()xxxxxxxx>newline.txt, which surely doesn't work. You need to construct a proper shell command inside the awk string, and obey awks string concatenation rules, i.e. your intended script should look like this (which is still broken, because $0 is not properly quoted in the resulting shell command):

awk '/^-/ { system("echo " $0 " > newline.txt") }'

However, if you really just need to echo $0 into a file, you can simply do:

awk '/^-/ { print $0 > "newline.txt" }'

Or even more simply

awk '/^-/' > newline.txt

Which essentially applies the default operation to all records matching /^-/, whereby the default operation is to print, which is short for neatly printing the current record, i.e. this script simply filters out the desired records. The > newline.txt redirection outside awk simply puts it into a file.

Robin479
  • 1,606
  • 15
  • 16
  • Thanks. My actual aim was to write output to a file in a different directory. The directory name is represented by a variable in awk. So i used your help and did this : awk ' / ^ - / { print $0 > dirNameVariable"/newline.txt" } ' however i got an error that said : awk : cannot open "design/newline.txt" for output (No such file or directory) Any idea why? (design is the value that the variable dirNameVariable holds in awk) – Deeraj Theepshi May 16 '18 at 09:51
  • You have to make sure that the directory actually exists – either relative to the current directory from which you invoke `awk`, or as an absolute path expression. And write permissions are required as well, of course. – Robin479 May 16 '18 at 13:00
2

You don't need the system, echo commands, simply:

awk '/^-/ {print $1}' file > newfile

This will capture lines starting with - and truncate the rest if there's a space.

awk '/^-/ {print $0}' file > newfile

Would capture the entire line including spaces.

You could use grep also:

grep -o '^-.*' file > newfile

Captures any lines starting with -

grep -o '^-.*().*' file > newfile

Would be more specific and capture lines starting with - also containing ()

l'L'l
  • 44,951
  • 10
  • 95
  • 146
  • 1
    I would recommend using `print $0` to print the whole line instead of `print $1` because you never know if there is a space in the `xxxx()xxxx`, also `awk` might be an overkill for this task a `grep` command would be more than enough ;-) – Allan May 16 '18 at 08:55
  • @Allan: The OP should indicate that the string has a space in it (edit question). And yes I was going to suggest grep also, but it's really up to them. – l'L'l May 16 '18 at 08:56
  • it is not my question lol hahaha you never know what OP **really** wants ;-) – Allan May 16 '18 at 08:57
  • 1
    nice recap answer +1! :) :) – Allan May 16 '18 at 09:16
2

First of all for simple extraction of patterns from file, you do not need to use awk it is an overkill, grep would be more than enough for the task:

INPUT:

$ more file
123
-xxxxxxxx()xxxxxxxx
abc
-xyxyxxux()xxuxxuxx
123
abc
123

command:

$ grep -oE '^-[^(]+\(\).*' file                                                                                                  
-xxxxxxxx()xxxxxxxx
-xyxyxxux()xxuxxuxx

explanations:

Option: -oE to define the output as the pattern and not the whole line (can be removed) Regex: ^-[^(]+\(\).* will select lines that starts with - and contains ()

You can redirect your output to a new_file by adding > new_file at the end of your command.

Allan
  • 12,117
  • 3
  • 27
  • 51
  • 1
    Youre welcome. You do need to add the `-E` for `+` though, or maybe escaping the `+` would be enough in your grep, idk. The point is that `+` in a BRE is just a literal character and grep uses BREs by default so while you don't need `-P` you do need something... – Ed Morton May 17 '18 at 04:14