Skip to main content
deleted 4 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path. When you use it in a glob as argument of ls -d, you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

note: I added an echo /./ so that awk doesn't need an END block

As you can see, the trick isyou need to start a relative path with ././, and an absolute path with /./.


I have to say, this trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path. When you use it in a glob as argument of ls -d, you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

note: I added an echo /./ so that awk doesn't need an END block

As you can see, the trick is to start a relative path with ././, and an absolute path with /./.


I have to say, this trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path. When you use it in a glob as argument of ls -d, you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

note: I added an echo /./ so that awk doesn't need an END block

As you can see, you need to start a relative path with ././, and an absolute path with /./.


I have to say, this trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

added 176 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path.
 When you use it in a glob and as argument of ls -d then, you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

note: I added an echo /./ so that awk doesn't need an END block

As you can see, the trick is to start a relative path with ././, and an absolute path with /./.


I have to say, thethis trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path.
 When you use it in a glob and as argument of ls -d then you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

I have to say, the trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path. When you use it in a glob as argument of ls -d, you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

note: I added an echo /./ so that awk doesn't need an END block

As you can see, the trick is to start a relative path with ././, and an absolute path with /./.


I have to say, this trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

added 4 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path.
When you use it in a glob and as argument of ls -d then you'll be able to parse itsthe output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX limitations might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

I have to say, the trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path.
When you use it in a glob as argument of ls -d then you'll be able to parse its output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX limitations might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

I have to say, the trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

Added for completeness sake

There's a trick called “slash dot saves the day” which consists in using /./ as a magic anchor for determining if a newline was produced as a record separator or due to embedded newlines in the path.
When you use it in a glob and as argument of ls -d then you'll be able to parse the output accurately.

Limitations

  • Requires the use of a glob, so ARG_MAX might kick in at some point.

  • Not all options of ls can be parsed. For example ls -dl adds symlink ‑> target to the output, which makes the boundary between the symlink and the target ambiguous.

  • Might be useless for non-POSIX compliant implementations of ls.


Here's an example that converts the output of ls -dnL, ls -drt, etc... into a TSV with C-style escaping:

{ command -p ls -dnL ././* /./*; echo /./; } |

LANG=C command -p awk -F '/[.]/' '
    function tsv_escape(s) {
        gsub(/\\/,"&&",s)
        gsub(/\n/,"\\n",s)
        gsub(/\t/,"\\t",s)
        gsub(/\r/,"\\r",s)
        return s
    }
    {
        if ( NF == 2 ) {
            if ( NR > 1 )
                print fields "/./" tsv_escape(filename)
            fields = $1
            filename = $2
            gsub(/[[:space:]]+/, "\t", fields)
        } else
            filename = filename "\n" $0
    }
'

I have to say, the trick would only be useful for systems that don't have GNU tools nor perl/python/zsh/etc... which is probably a non-existent use-case nowadays.

edited body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 143 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
edited body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
edited body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 1 character in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
edited body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 9 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 159 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 4 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
deleted 1 character in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 6 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 183 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 64 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
added 22 characters in body
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading
Source Link
Fravadona
  • 1.6k
  • 5
  • 14
Loading