For years, UNIX has supported spaces in filesnames but most applications refrained from creating files with spaces because of the headaches this might cause when dealing with properly quoting these filenames.

The simple solution is to use find’s -print0 argument or use xargs -d '\n' argument.

find . -type f -print0 | xargs -0 list_args
# or 
mkfl
cat src.fl | xargs -d '\n' -n 1 xargs list_args

Common issues

This section explains the most common issue. Scripts that don’t properly quote arguments that are passed in from the command line.

#!/bin/bash
echo "Hello $1"

When executed hello Bob Smith prints “Hello Bob”. The solution is to quote the first argument as hello "Bob Smith". Another is to change the script to handle multiple arguments, for example, echo "Hello $*"

This issue becomes very clear when dealing with files.

touch file1.txt
touch "file2 with spaces.txt"
find . -type f | grep file[12] | xargs -I{} echo this is file: {}

I wrote the following script to learn about how this works

list_args "a b c" ddd eee fff
echo "$*" output is:
a b c ddd eee fff
****************************************************************
Using        >>>     for iarg in "$*"     <<<         output is:
"$*" Arg expanded arg is: [a b c ddd eee fff]
****************************************************************
Using        >>>     for iarg in  $*      <<<         output is:
$* Arg expanded arg is: [a]
$* Arg expanded arg is: [b]
$* Arg expanded arg is: [c]
$* Arg expanded arg is: [ddd]
$* Arg expanded arg is: [eee]
$* Arg expanded arg is: [fff]
****************************************************************
Using        >>>     for iarg in "$@"     <<<         output is:
"$@" Arg expanded arg is: [a b c]
"$@" Arg expanded arg is: [ddd]
"$@" Arg expanded arg is: [eee]
"$@" Arg expanded arg is: [fff]
****************************************************************
Using        >>>     for iarg in  $@      <<<         output is:
$@ Arg expanded arg is: [a]
$@ Arg expanded arg is: [b]
$@ Arg expanded arg is: [c]
$@ Arg expanded arg is: [ddd]
$@ Arg expanded arg is: [eee]
$@ Arg expanded arg is: [fff]
****************************************************************
Using        >>>     $1 through $9      <<<         output is:
1: [a b c]
2: [ddd]
3: [eee]
4: [fff]
5: []
6: []
7: []
8: []
9: []

The list_args script is shown below

#!/bin/bash

echo 'echo "$*" output is:'
echo "$*"

echo '****************************************************************'
echo 'Using        >>>     for iarg in "$*"     <<<         output is:'
for iarg in "$*"
do
    echo '"$*" Arg expanded arg is:' "[$iarg]"
done

echo '****************************************************************'
echo 'Using        >>>     for iarg in  $*      <<<         output is:'
for iarg in $*
do
    echo '$* Arg expanded arg is:' "[$iarg]"
done

echo '****************************************************************'
echo 'Using        >>>     for iarg in "$@"     <<<         output is:'
for iarg in "$@"
do
    echo '"$@" Arg expanded arg is:' "[$iarg]"
done

echo '****************************************************************'
echo 'Using        >>>     for iarg in  $@      <<<         output is:'
for iarg in $@
do
    echo '$@ Arg expanded arg is:' "[$iarg]"
done

echo '****************************************************************'
echo 'Using        >>>     $1 through $9      <<<         output is:'
echo "1: [$1]"
echo "2: [$2]"
echo "3: [$3]"
echo "4: [$4]"
echo "5: [$5]"
echo "6: [$6]"
echo "7: [$7]"
echo "8: [$8]"
echo "9: [$9]"

if [ "$#" -gt 9 ]
then
	loop_cnt=10
	shift; shift; shift; shift; shift
	shift; shift; shift; shift
	while [ $# -ge 1 ]
	do
		echo "$loop_cnt: [$1]"
		loop_cnt=`expr $loop_cnt + 1`
		shift
	done
fi


<
Previous Post
Windows when did I login?
>
Next Post
Notes on using jq (JSON Query Language)