The command 'find' inside awk does not work - awk

Looking for hidden files:
$ find . -type f -not -name "."
./.kjj.jpg
./2.jpg.~1~
Now, using the same commands, but inside awk:
$ awk 'BEGIN{ system(find . -type f -not -name ".") }'
awk: 1: unexpected character '.'
Why does it not work?

$ awk 'BEGIN{ system("find . -type f -not -name \".\"") }'
The system() function accepts a string; find . -type... withut quotes is simply invalid AWK syntax.

Related

Make 'awk' exit if it is given an empty file list from a subshell

I run:
find mydir -type f -name "the_thing.txt"
And I get nothing (the file is not there).
Then I run:
awk '{print $0}' $(find mydir -type f -name "the_thing.txt")
And I get the shell stuck in awk (because the input file was not specified, and awk is now waiting for standard input).
How can I make awk (or cat) just print nothing and exit in case find does not output anything?
Your previous post included the -maxdepth 1 option which uniquifies the file path.
That is why I've asked about that. Now the option is removed and I've understood what you mean by some subdirectory.
Then would you please try:
find mydir -type f -name "the_thing.txt" -print0 | xargs -0 -r awk '{print $0}'
Please note that the -r option to xargs suppresses the execution if the input is empty.
If you want to limit the file up to one with head command, you can say:
find mydir -type f -name "the_thing.txt" -print0 | head -n1 -z | xargs -0 -r awk '{print $0}'
The -z option to head was introduced in coreutils 8.25 (around January 2016).
If your head command does not support the option, please say alternatively:
find mydir -type f -name "the_thing.txt" | head -n1 | xargs -r awk '{print $0}'
which is less robust against the filenames which contain blank characters.

Make work find pipe awk command in Makefile

I have this find awk line to get python code analyse::
$ find ./ -name '*.py' -exec wc -l {} \; | sort -n| awk '{print $0}{s+=$0}END{print s}'
12 ./gb/__init__.py
23 ./gb/value_type.py
40 ./setup.py
120 ./gb/libcsv.py
200
$
I try to put it in a Makefile::
$ cat Makefile
python_count_lines: clean
#find ./ -name '*.py' -exec wc -l {} \; | sort -n| awk '{print \$0}{s+=\$0}END{print s}'
But this did not work::
$ make python_count_lines
awk: line 1: syntax error at or near }
Makefile:12: recipe for target 'python_count_lines' failed
make: *** [python_count_lines] Error 2
$
Bertrand Martel is correct that you need to escape dollar signs from make by doubling them, not prefixing them with backslashes (see info here).
However, the rest of that suggestion is not right and won't work; first, you should almost never use the shell function in a recipe. Second, using the info function here cannot work because in the first line you've set a shell variable RES equal to some value, then you try to print the make variable RES in the second line; not only that but each line is run in a separate shell, and also all make variable and function references are expanded up-front, before any part of the recipe is passed to the shell.
You just need to do this:
python_count_lines: clean
#find ./ -name '*.py' -exec wc -l {} \; | sort -n| awk '{print $$0}{s+=$$0}END{print s}'

How to use $1, $n from awk in Makefile

I have this to get the number of lines of my python files with relative path and correct padding for number of lines:
$ find ./ -name "*.py" -exec wc -l {} \;| awk '{printf "%10s %s\n", $1, $2}'
29 ./setup.py
28 ./proj_one/setup.py
896 ./proj_one/proj_one/data_ns.py
169 ./proj_one/proj_one/lib.py
310 ./proj_one/proj_one/base.py
0 ./proj_one/proj_one/__init__.py
72 ./proj_one/tests/lib_test.py
I would like to have it in a Makefile::
$ cat Makefile
pfile_wc:
#find ./ -name "*.py" -exec wc -l {} \;| awk '{printf "%10s %s\n", $1, $2}'
So I could call it with:
$ make pfile_wc
I can't get to properly escape/use the $1 and $2 in the Makefile
You have to prepend your $ symbol with another one:
#find ./ -name "*.py" -exec wc -l {} \;| awk '{printf "%10s %s\n", $$1, $$2}'

Why is this printf cmd failing

find . -name '.git' -exec printf %q "'{}'" \; ;
printf: illegal format character q
It seems the problem is that the printf being called is not bashes builtin printf Is there any way to use builtin printf ?
Just call bash and give it an inline script to invoke printf:
find . -name '*.txt' -exec bash -c "printf %q\\\\n {}" \;

Get total number of lines of code?

Does anyone know if it is possible to get the total number of lines of code from all the classes in my project in Objective-C.
Right now I am guessing that this is not possible but I just wanted to make sure.
If it is possible does anyone know how to do it?
If you like the terminal and have all your files in the same folder, try:
$ wc *.m
To get at the number in your code, you could run it as a shell script build phase that generates a header file for you. E.g.
cd source_folder
wc -l *.m \
| tail -1 \
| awk '{ print "#define kNumberOfLines " $1 }' \
> lines_of_code_header.h
Then include that file and use the constant as you like.
find . -type f -name "*.[mh]" -exec wc -l '{}' \; | awk '{sum+=$1} END {print sum}'