Skip to main content
Correct the name of the alias; explain the "hidden files" name filter; mention shellcheck
Source Link
AdminBee
  • 22.9k
  • 24
  • 50
  • 74
  1. You have a space behind the =. This will actually make the alias lllh undefined (at least in bash).
  2. You enclosed the alias definition in backticks (`), probably in an attempt to create a "third layer" of quoting. However, backticks are the (albeit now deprecated) syntax for command substitution, i.e. lllh would contain the console output of the ll | awk ... pipeline and try to execute that as a command.
  3. You rely on a command ll being either present or at least pre-defined as an alias of ls -l. This may or may not be the case.
  4. Your awk program starts has the single-quotes and the curly braces in the wrong order. The correct syntax is awk ' { ... } '.

Note that if this is part of a shell script, you may want to run it through shellcheck, also available as standalone tool on many Linux distributions, to catch many syntax-related errors.

alias ll="lslh="ls -lh | awk '{print  \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"
  • the advice found in one of the answers to the question you linked - defining a function - is a far better way to get out of the "quoting hell" (as mentioned by @ilkkachu), so something like

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    is much cleaner and easier to understand

  • I would recommend to avoid parsing ls altogether, and propose the following find-based alias instead:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

    The ! -name ".*" filter is used to emulate the standard behavior of ls to ignore hidden files. If you want them listed, you can leave that part out.

  1. You have a space behind the =. This will actually make the alias ll undefined (at least in bash).
  2. You enclosed the alias definition in backticks (`), probably in an attempt to create a "third layer" of quoting. However, backticks are the (albeit now deprecated) syntax for command substitution, i.e. ll would contain the console output of the ll | awk ... pipeline and try to execute that as a command.
  3. You rely on a command ll being either present or at least pre-defined as an alias of ls -l. This may or may not be the case.
  4. Your awk program starts has the single-quotes and the curly braces in the wrong order. The correct syntax is awk ' { ... } '.
alias ll="ls -lh | awk '{print  \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"
  • the advice found in one of the answers to the question you linked - defining a function - is a far better way to get out of the "quoting hell" (as mentioned by @ilkkachu), so something like

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    is much cleaner and easier to understand

  • I would recommend to avoid parsing ls altogether, and propose the following find-based alias instead:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

  1. You have a space behind the =. This will actually make the alias lh undefined (at least in bash).
  2. You enclosed the alias definition in backticks (`), probably in an attempt to create a "third layer" of quoting. However, backticks are the (albeit now deprecated) syntax for command substitution, i.e. lh would contain the console output of the ll | awk ... pipeline and try to execute that as a command.
  3. You rely on a command ll being either present or at least pre-defined as an alias of ls -l. This may or may not be the case.
  4. Your awk program starts has the single-quotes and the curly braces in the wrong order. The correct syntax is awk ' { ... } '.

Note that if this is part of a shell script, you may want to run it through shellcheck, also available as standalone tool on many Linux distributions, to catch many syntax-related errors.

alias lh="ls -lh | awk '{print  \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"
  • the advice found in one of the answers to the question you linked - defining a function - is a far better way to get out of the "quoting hell" (as mentioned by @ilkkachu), so something like

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    is much cleaner and easier to understand

  • I would recommend to avoid parsing ls altogether, and propose the following find-based alias instead:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

    The ! -name ".*" filter is used to emulate the standard behavior of ls to ignore hidden files. If you want them listed, you can leave that part out.

Add function-based solution, as recommended by @ilkkachu and one of the answers in the linked Q
Source Link
AdminBee
  • 22.9k
  • 24
  • 50
  • 74

However, in order to avoid parsing ls, I would propose the following find-based alias instead:However

alias lh='find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"'

which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

  • the advice found in one of the answers to the question you linked - defining a function - is a far better way to get out of the "quoting hell" (as mentioned by @ilkkachu), so something like

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    is much cleaner and easier to understand

  • I would recommend to avoid parsing ls altogether, and propose the following find-based alias instead:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

However, in order to avoid parsing ls, I would propose the following find-based alias instead:

alias lh='find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"'

which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

However

  • the advice found in one of the answers to the question you linked - defining a function - is a far better way to get out of the "quoting hell" (as mentioned by @ilkkachu), so something like

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    is much cleaner and easier to understand

  • I would recommend to avoid parsing ls altogether, and propose the following find-based alias instead:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.

Source Link
AdminBee
  • 22.9k
  • 24
  • 50
  • 74

There are several syntax issues with your alias definition. However, the first problem is that parsing the output of ls is strongly discouraged because code that involves it will ultimately stumble upon files with "non-trivial" characters such as spaces, tabs and newlines. In addition, in particular the output format of the timestamp may change depending on how "old" the file actually is, meaning that you can have more or less space-separated "fields" in the input to awk depending on the actual file, or one of the fields changing its meaning (e.g. from year in case of an "old file" to time of the day for a "recent file"). These two aspects are what @steeldriver referred to as the alias being "fragile".

The "obvious" issues are:

  1. You have a space behind the =. This will actually make the alias ll undefined (at least in bash).
  2. You enclosed the alias definition in backticks (`), probably in an attempt to create a "third layer" of quoting. However, backticks are the (albeit now deprecated) syntax for command substitution, i.e. ll would contain the console output of the ll | awk ... pipeline and try to execute that as a command.
  3. You rely on a command ll being either present or at least pre-defined as an alias of ls -l. This may or may not be the case.
  4. Your awk program starts has the single-quotes and the curly braces in the wrong order. The correct syntax is awk ' { ... } '.

The immediate solution to the problem you experience is indeed the correct quoting and escaping. You could try something like

alias ll="ls -lh | awk '{print  \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"

where the alias is everything in the " ... ", the input to awk is explicitly stated as ls -lh, the awk program is enclosed in single quotes, and the field references inside the awk program are protected from premature interpretation as shell positional parameters at "definition-time of the alias" by backslash-escaping (so that awk actually sees them as $9 and not replaced by the 9th positional parameter of the shell instance, which is likely empty).

However, in order to avoid parsing ls, I would propose the following find-based alias instead:

alias lh='find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"'

which uses the printf formatting options of find to reliably output the desired file properties. The only drawback is that there is no -h option for human-readable sizes.