Awk to replace a single quote

I want to replace all include('./ with a set of files using include(' . I am trying to use awk as follows:

 awk '{gsub("include\('"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php 

He gives me this error.

 awk: (FILENAME=xyz.php FNR=1) fatal: Unmatched ( or \(: /include('.// 

Any help would be appreciated.

+4
source share
4 answers

@OP, you can try using the octal code for a single quote ( \047 ) and a slash ( \057 ), for example

 $ cat file include('./ $ awk '{gsub(/include\(\047\.\057/ , "include(\047" ) }1' file include(' 
+12
source

This works (without redirecting I / O to "print"):

 awk '{gsub(/include\('"'"'.\//, "include\('"'"'", $0); print }' # Wrong awk '{gsub(/include\('"'"'.\//, "include('"'"'", $0); print }' # Right 

It displays this input:

 include('./abc') include('x/abc') 

in

 include('abc') include('abc') 

Empirically, the regex seems to be inside slashes; The replacement string should be a regular string. You will need to display ' . 'to' \. 'to stop the second substitution.

I am not very happy with this explanation. The man page for awk on MacOS X says:

/ re / - constant regular expression; any string (constant or variable) can be used as a regular expression, except for the position of an isolated regular expression in the template.

So, the theoretically used string should work. Empirically, this is not so; I got essentially the same error message as with your code. And you have the right quotation marks, which is not trivial.

Perl can sometimes be simpler (because you can choose an arbitrary delimiter to mark the borders of the regular expression):

 perl -pe "s%include\('\./%include('%g" 
+2
source

Try the following:

 awk '{gsub("include(\'"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php 

you have lost the backslash

or that:

  awk '{gsub("include(\'./", "include(\'", $0); print > FILENAME}' *.php 

how about this?

 awk '{gsub("include(\47./", "include(\47", $0); print > FILENAME}' *.php 

Have you tried without too much noise?

 awk '{gsub("include('./", "include('", $0); print > FILENAME}' *.php 
0
source

You don’t need to use awk if all you want to do is. :) Also, writing to a file when you read it in the form in which you did it will result in data loss or corruption , try not to of this.

 for file in *.php ; do # or, to do this to all php files recursively: # find . -name '*.php' | while read file ; do # make backup copy; do not overwrite backup if backup already exists test -f $file.orig || cp -p $file $file.orig # awk '{... print > NEWFILE}' NEWFILE="$file" "$file.orig" sed -e "s:include('\./:include(':g" "$file.orig" >"$file" done 

Just to clarify the aspect of data loss: when awk (or sed ) starts processing the file, and you ask them to read the first line, they will actually perform buffered reads, that is, they will read from the file system (let it simplify and say "from disk") a data block the size of its internal read buffer (for example, 4-65 KB) to improve performance (by reducing disk I / O). Suppose a file re working with larger than the size of the buffer. Further readings will come from the buffer until the buffer is exhausted, after which the second block of data will be loaded from the disk into the buffer, etc.

However, immediately after reading the first line, i.e. after the first block of data is read from the disk into the buffer, your awk script opens FILENAME , the input file itself for writing with truncation , i.e. file size on disk reset to 0 . For now, all that remains of your source file is the first few kilobytes of data in awk memory. awk will continue to read line after line from the buffer in memory and produce output until the buffer is exhausted, at which point awk will probably stop and leave you with a 4-65k file.

As a side note, if you are actually using awk to expand (for example, print "PREFIX: " $0 ), do not shorten ( gsub(/.../, "") ) the data, then you will almost certainly get an immutable awk and ever-growing file. :)

0
source

Source: https://habr.com/ru/post/1302346/


All Articles