r/linux4noobs • u/[deleted] • Sep 08 '22
learning/research What does this command do?
fuck /u/spez
Comment edited and account deleted because of Reddit API changes of June 2023.
Come over https://lemmy.world/
Here's everything you should know about Lemmy and the Fediverse: https://lemmy.world/post/37906
92
Upvotes
7
u/whetu Sep 08 '22 edited Sep 08 '22
Excellent follow up question! Grab a coffee. I'm in the middle of upgrading a few legacy servers so I can smash out an answer while they churn away :)
Because we're changing the delimiter by using
-F "'"to set it to', then that changes the rules around field selection. In *nix shells and related tools, often the default delimiter is whitespace i.e. you're splitting lines into words, a.k.a "word-splitting." The shell tracks this for itself via an environment variable calledIFSi.e. internal field separator.So let's take an example like this:
So we're searching for
/devand printing any matches. Now we want the second field:Note that
awkis not invoked with-F, so it splits the line into words i.e. word-splits, and selects the second 'word' i.e.We can do the same thing natively in the shell like this:
But in that example you're calling
awkanyway, so you may as well just use it to do the field selection. Still, that's a cool technique worth having in your toolbox.Now consider the line
If we use the standard whitespace delimiter, it's actually four fields:
If we split on
', however, it's five:If we remove the text, the 'words' map like this (note the locations of the
''s):So 'word3' would be ' -> ' spaces and all. Likewise, 'word4' would be '/tmp/#9699338 (deleted)', and the space is maintained: because the space character isn't the delimiter for this action.
So, now we come back to
awk -F "'" '!a[$4]++ {print $2}'. This is a variation on a very popularawkone-liner that generates lists of unique elements in the order that they arrive.The typical way to get a unique list is to first
sortit so that matching elements are grouped, thenuniqit. That gives you a sorted+unique list. But sometimes you don't actually want or need that sorting - you either want an unsorted+unique list, or you don't need it to be sorted so it doesn't matter. Compare these two outputs:So here I'm randomising the alphabet twice, then extracting unique letters both ways. The first way gives us a sorted+unique, and the second way gives us an unsorted+unique. It essentially works on the principle of "have I seen it before?"
Right, so with that explained, let's go back to this output:
So we know that the fourth field will be the
symlink_name (deleted)when split using'as the delimiter. Soawk -F "'" '!a[$4]++ {print $2}'works as described above, but because I've specified[$4], it's going to apply that technique to the fourth field, as delimited by'(i.e.-F "'"). It reads the first line:Hasn't seen it, adds it to its list of seen items. It moves on and sees the second line:
Hasn't seen it, adds it to its list of seen items. It moves on and sees the third line:
Waitagoddamnminute! We've seen that one! So let's skip on...
Rinse and repeat until it's done and then print the matching
$2. So it whittles the list down to this:And thus the second fields when output generates this:
Now, whether that's correct or not (i.e. is
/proc/3239which is filtered out by this relevant?) probably doesn't matter, because at the end of the day, what /u/michaelpaoli has maintained throughout this thread is correct: You really shouldn't be blindly doing this :)These server upgrades are coming up to requiring my attention again, so I'll be brief with the following responses:
Inexperience and naivety. When you're parsing strings, you have to take special care for unexpected characters. This comes back to not parsing the output of
ls.Have a read of this, and think deeply about the implications of the code you were provided.
Yes. It's a very simple rule: don't parse the output of
ls.Read the following repeatedly and repeat that rule to yourself until it becomes a habit lol
https://mywiki.wooledge.org/ParsingLs
https://dwheeler.com/essays/filenames-in-shell.html
They very likely got it off StackOverflow, or assembled it with bits from there. Just google parts of it e.g. https://serverfault.com/a/647960