[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: bash read and field separator



On Thu, Dec 08, 2022 at 09:53:37PM +0700, Max Nikulin wrote:
> On 07/12/2022 19:18, Greg Wooledge wrote:
> > 
> > rlart() {
> >    local day time path
> >    find "${1:-.}" -type f -printf '%T@ %TY-%Tm-%Td %TT %p\0' |
> >      sort -zn |
> >      while read -rd '' _ day time path; do
> >        printf '%s %s %s\n' "$day" "${time%.*}" "$path"
> >      done
> > }
> 
> I was not aware of the "read -d ''" feature that allows to work with
> null-terminated records, so thank you for the hint. However the read command
> strips leading and trailing spaces and newlines from path. What is the best
> way to preserve them?

Well, let's see.

unicorn:~$ find .bashrc -printf '%T@ %TY-%Tm-%Td %TT %p\0'
1670415288.2197120110 2022-12-07 07:14:48.2197120110 .bashrcunicorn:~$ 

> I have tried slash (a character disallowed in file
> names) instead of space as field separator:

The "problem" with that is we have slashes in our pathnames (%p) in
almost all cases.  But if we carefully build the read command, I
think it should keep them intact.

unicorn:~$ find ./.bashrc -printf '%T@/%TY-%Tm-%Td/%TT/%p\0' ; echo
1670415288.2197120110/2022-12-07/07:14:48.2197120110/./.bashrc

Yes, that looks OK for parsing with a fixed number of variables on the
read command.  Just gotta add IFS=/ and we're good to go.

After editing .bashrc to have this:

rlart() {
  local day time path
  find "${1:-.}" -type f -printf '%T@/%TY-%Tm-%Td/%TT/%p\0' |
    sort -zn |
    while IFS=/ read -rd '' _ day time path; do
      printf '%s %s %s\n' "$day" "${time%.*}" "$path"
    done
}

let's do a bit of testing:

unicorn:~$ rlart tmp | tail -n5 | sed -n l
2021-08-23 13:10:38 tmp/mawk-1.3.4-20200120/fcall.o$
2021-08-23 13:10:38 tmp/mawk-1.3.4-20200120/version.o$
2021-08-23 13:10:38 tmp/mawk-1.3.4-20200120/mawk$
2022-12-07 18:52:30 tmp/shot.png$
2022-12-08 11:46:11 tmp/  spaces  $

Looks correct.


Reply to: