-1

I know that I may have the C package #include <stdint.h> in the first 1-30 lines. I would like to add it to lines where no previously if the file contains the word LARGE_INTEGER by GNU tools.

Substitute [0,1] matches

I thought first about replacing [0,1] matches always as follows but now I think the extra substitution is unnecessary so should be avoided:

gsed -i '1-30s/^(#include <stdint.h>\n)?/#include <stdint.h>\n/'

I propose to reject this.

Extra ggrep approach to say no match

I think this may be a good solution because it first looks the conditions and then substitutes if necessary. This thread suggests to add an extra grep so code where the while loop structure is from here

while read -d '' -r filepath; do                                \
    [ "$(ggrep -l "LARGE_INTEGER" "$filepath")" ] &&            \
    [ "$(ggrep -L "#include <stdint.h>" "$filepath") ]          \
    | gsed -i '1s/^/#include <stdint.h>\n/' "$filepath"
done

which however gives

test.sh: line 5: stdint.h: No such file or directory

and does add the package to lines without #include <stdint.h> too which is wrong.

How can you combine two conditional statements for SED efficiently?

  • 1
    Masi, I've already explained in my answer to your other question how to chain actions with find. See my updated post for a generic example but really, you should make an effort and try to understand how it works (the man page is your best friend). Believe me, it will pay off in the long run. Regards. – don_crissti Jun 30 '15 at 19:04
  • @don_crissti Yes, you are right. Thank you for the update! Yes, I today experienced and learned that your method is excellent because searching Fixed Strings in quiet mode is efficient and extensible for regex too. I think I should not need these while loops when I have find -qF -size -15k ... {} \;. – Léo Léopold Hertz 준영 Jun 30 '15 at 19:36

1 Answers1

2

I'm not sure I decrypted your prose correctly. The script below adds #include <stdint.h> to files in the current directory that (1) contain the word LARGE_INTEGER, and (2) don't already include <stdint.h>:

sed -i -e '1i\' -e '#include <stdint.h>' $(
    egrep -c '#include +<stdint\.h>' $( fgrep -lw LARGE_INTEGER * ) | \
        sed -n '/:0$/ { s/:0$//; p; }')

The script assumes GNU sed (for -i).

In detail:

  • fgrep -lw LARGE_INTEGER * lists the files in the current directory that contain the word LARGE_INTEGER
  • egrep -c '#include +<stdint\.h>' counts the occurrences of #include <stdint.h> through the files found by fgrep above
  • sed -n '/:0$/ { s/:0$//; p; }' selects the files with 0 matches and keeps only the filenames
  • sed -i -e '1i\' -e '#include <stdint.h>' adds a first line #include <stdint.h> to the files found above.
lcd047
  • 7,238