Você tem a maioria dos detalhes técnicos, mas acho que está perdendo a semântica da coisa toda.
As aspas simples em '^d' mantêm qualquer shell executado por esse pipeline de tratar caracteres na expressão regular (que é '^d' ) como "especial". Por exemplo, $ é a expressão regular que significa "fim de linha". Os shells também usam $ para marcar o próximo token como uma variável do shell, cujo valor deve ser interpolado na string. O ^ é um sinônimo antigo para | , o stdout do cano do lado esquerdo em stdin do lado direito. As citações únicas mantêm ^ de tratamento especial.
A semântica não deve passar nenhuma linha de ls -l output marcada como diretórios. ls -l coloca um 'd' como o primeiro caractere de qualquer linha pertencente a um diretório.
A opção -g para sort faz com que o comando procure representações de números no campo-chave e classifique de acordo com o valor numérico, não como sequências. A ordem de classificação padrão é menor para a maior, portanto, a opção -r faz com que ela seja classificada de maior para menor. O -k 5 diz para usar o campo # 5 como o campo-chave. sort usa caracteres de espaço em branco (espaços em branco, tabulações, etc.) para dividir uma linha de texto em "campos" por padrão. Na minha caixa Arch Linux, o 5º campo separado por espaço em branco de ls -l é o tamanho do arquivo em bytes.
Semântica aqui está classificando arquivos por tamanho em bytes, maior primeiro.
Você está classificando arquivos (não diretórios) por tamanho em bytes e colocando as informações sobre os dois maiores arquivos no arquivo de texto.
Editorial, é geralmente considerado de má forma para analisar a saída de ls ; veja Por que você não deve analisar a saída de ls (1) . Historicamente, ls tinha formatos diferentes em máquinas diferentes, e um script que assumia, digamos que o tamanho do arquivo fosse o campo 5, daria problemas difíceis de entender em outra máquina. Então cuidado com isso.