Skip to main content
made null-delimited mapfile version explicit
Source Link
steeldriver
  • 83.9k
  • 12
  • 124
  • 175

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provideprovides a null-delimited mapfile1, then you can modify that to IFS= mapfile -t -d '' files < <(find . -type f -print0) . Otherwise, assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

1 the -d option was added to mapfile in bash version 4.4 iirc

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provide a null-delimited mapfile1, then you can assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

1 the -d option was added to mapfile in bash version 4.4 iirc

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version provides a null-delimited mapfile1, then you can modify that to IFS= mapfile -t -d '' files < <(find . -type f -print0) . Otherwise, assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

1 the -d option was added to mapfile in bash version 4.4 iirc

added 106 characters in body
Source Link
steeldriver
  • 83.9k
  • 12
  • 124
  • 175

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provide a null-delimited mapfile1, then you can assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

1 the -d option was added to mapfile in bash version 4.4 iirc

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provide a null-delimited mapfile, then you can assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provide a null-delimited mapfile1, then you can assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines 

1 the -d option was added to mapfile in bash version 4.4 iirc

Source Link
steeldriver
  • 83.9k
  • 12
  • 124
  • 175

If you only need to handle spaces and tabs (not embedded newlines) then you can use mapfile (or its synonym, readarray) to read into an array e.g. given

$ ls -1 file other file somefile 

then

$ IFS= mapfile -t files < <(find . -type f) $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file #? 3 ./other file 

If you do need to handle newlines, and your bash version does not yet provide a null-delimited mapfile, then you can assemble an equivalent array from null-delimited find output using a read loop:

$ touch $'filename\nwith\nnewlines' $ $ files=() $ while IFS= read -r -d '' f; do files+=("$f"); done < <(find . -type f -print0) $ $ select f in "${files[@]}"; do ls "$f"; break; done 1) ./file 2) ./somefile 3) ./other file 4) ./filename with newlines #? 4 ./filename?with?newlines