figure out the complicated command

d_vincent

New Member
Joined
Aug 24, 2020
Messages
3
Reaction score
0
Credits
27
Hi everyone, I am trying to figure out the command below;
Code:
find ./ -type f | awk -F / -v OFS=/ '{$NF="";dir[$0]++} END {for (i in dir) print diri}'
the output is like:
Code:
6./Release_1_18_1_0_06_26/metadata/3_Control_Files/
5./Release_1_18_1_0_06_26/metadata/7_SAS_Code/
5./Release_1_18_1_0_06_26/others/1_content/
1./.cache/pip/selfcheck/
2./Release_1_18_1_0_06_26/metadata/5_Status/
1./Release_1_18_1_0_06_26/compute/2_packages/
1./sasuser.v94/
4./metadata/FR1_Release_1.17.1.1/3_Control_Files/
4./Release_1_18_1_0_06_26/metadata/6_Patches/
This command am counting the number of incode in the current path. However, I did not understand
Code:
{$NF="";dir[$0]++} END {for (i in dir) print dir[i]i}
, especially
Code:
dir[$0]
. anyone can explain that?
 
Last edited:


As it stands - I have no idea what that is doing.

Running the exact command you have posted gives me an empty bunch of lines, so it doesn't seem to work at all.

BTW - This is what you posted:
Bash:
find ./ -type f | awk -F / -v OFS=/ '{$NF="";dir[$0]++} END {for (i in dir) print diri}'

Which looks completely wrong. diri isn't even declared as a variable.

However, because you failed to post your snippet in code blocks - I think the sites post editor has changed the formatting of some of your code. The italicised letters in your post indicate that this is probably the case.

So it would help if you repost the actual command you're using - INSIDE a code-block, so the original formatting of the code is kept.

In the box where you compose your posts on Linux.org there is a button with three dots "..." - that is the "Insert" button.
Press that and select "Code" in the menu and a dialog will popup that you can copy/paste your code into.

Alternatively - you can add the code blocks manually in your post by typing:
[code]
#Your code here
[/code]

Seeing as you don't understand it, I'm assuming you didn't write it. So where did you get this command from?
Can you explain more clearly what you're trying to do?
 
Hi, There exist typos in this command. I already figure out this command. The correct command should be:
Code:
find ./ -type f | awk -F / -v OFS=/ '{$NF="";dir[$0]++} END {for (i in dir) print dir[i]i}'

Regarding this command, Could you please go through the detailed explanation below.
Code:
find ./ -type f ### find the files in the current dir
| awk -F / -v OFS=/ ' ### setting field separator and output field separator as /
{
$NF=""; ### make the last field of current lines as NULL
dir[$0]++ ###creating the array with the current line and keep increasing its' value
} END {
for (i in dir) print dir[i]i ### print the array
}'

The command is to count inodes of current dir. The tricky part for me in this command is dir[$0]++ that has count functionality. The reason is located in dir[$0] which can record the last count of current line.
 
Ah, so the correct code was slightly mangled, but wasn’t hugely different!! I thought something definitely looked unusual about it.

And I agree, the first and last parts of the command are quite straightforward. The bit in the middle is very confusing.

AFAIK - $NF contains the number of fields in the current line, so from what I can see - it’s setting the number of fields to null. But I have no idea why, or what the purpose of this is.

And dir[$0]++ is a little confusing too. I can see that it’s setting up an array called dir. And ++ indicates that the value in the array at $0 is being incremented.
The only thing I don’t know is what $0 represents in this context.

Normally in a shell script, $0 would be the name of the command/script. But perhaps in this context it refers to the entire, current line of text that was piped from find.

So, perhaps by setting the number of fields ($NR) to null, we end up pre-pending the count to the start of the line?? Is that what this code is doing?!

Whatever it is doing, it seems very esoteric and hacky! It’s not immediately obvious what it’s doing!!

I’ll fire up my laptop at some point and will have a play with it and see what I can work out!
 
This command is to count the inodes in current dir. In other words. we want to know how many files in each children directories.
Code:
find ./ -type f ### find the files in all children directory
| awk -F / -v OFS=/ ' ### setting field separator and output field separator as /
{
$NF=""; ### make the last field of current lines as NULL
              ### The last field of the current lines is file name. if you want count the file in each directory.
              ### of course you need set it as Null. Because the filename is usually unique.

dir[$0]++ ###creating the array with the current line and keep increasing its' value
                 ### $0 means the current line in awk that deal with text line by line.
} END {
for (i in dir) print dir[i]i ### print the array
}'

Alternatively, how do you write dir[$0]++ by very cool format in your reply?
 

Members online


Top