Reputation: 533
I would like to output the list of items in a folder in the folowing way:
"filename1" "filename2" "file name with spaces" "foldername" "folder name with spaces"
In other words, item names must be in a single line, surrounded with quotes (single or double) and divided by spaces.
I know that
find . | xargs echo
prints output in a single line, but I do not know how to add quotes around each item name.
This code is part of a bsh script. The solution can therefore be a set of commands and use temporary files for storing intermediate output.
Thank you very much for any suggestion.
Cheers, Ana
Upvotes: 53
Views: 54910
Reputation: 30428
Try this...
find . -print0 | xargs -0 echo
the -print0
argument makes the output null-terminated instead of a new-line, and the -0
on xargs says to use null as the delimiter. As such, spaces are preserved as you would expect without the need to quote things.
Upvotes: 0
Reputation: 721
After 10 years, no one suggested the Bash "|while read" method?
find * -type d -depth 0|while read f; do echo \"$f\"; done
It's a simple Bash shell pipeline instead of launching another program like sed or xarg. If you really want to do something with each file/folder:
find * -type d -depth 0|while read f; do du -sh "$f"; done
By the way, find *
uses another Bash feature that excludes .xyz files/folders and will not output the ./
prefix find .
does.
Upvotes: 11
Reputation: 283043
To avoid hacks trying to manually add quotes, you can take advantage of printf
s %q
formatting option:
❯ ll .zshrc.d
total 112K
-rwxrwxrwx 1 root root 378 Jul 1 04:39 options.zsh*
-rwxrwxrwx 1 root root 57 Jul 1 04:39 history.zsh*
-rwxrwxrwx 1 root root 301 Jul 1 05:01 zinit.zsh*
-rwxrwxrwx 1 root root 79K Jul 1 05:19 p10k.zsh*
-rwxrwxrwx 1 root root 345 Jul 1 05:24 zplugins.zsh*
-rwxrwxrwx 1 root root 490 Jul 4 23:40 aliases.zsh*
-rw-r--r-- 1 root root 9.0K Jul 27 08:14 lscolors.zsh
-rw-r--r-- 1 root root 0 Aug 30 05:56 'foo bar'
-rw-r--r-- 1 root root 0 Aug 30 05:58 '"foo"'
❯ find .zshrc.d -exec printf '%q ' {} +
.zshrc.d .zshrc.d/history.zsh .zshrc.d/aliases.zsh .zshrc.d/zplugins.zsh .zshrc.d/p10k.zsh .zshrc.d/zinit.zsh .zshrc.d/options.zsh '.zshrc.d/"foo"' '.zshrc.d/foo bar' .zshrc.d/lscolors.zsh #
vs:
find .zshrc.d -printf "\"%p\" "
".zshrc.d" ".zshrc.d/history.zsh" ".zshrc.d/aliases.zsh" ".zshrc.d/zplugins.zsh" ".zshrc.d/p10k.zsh" ".zshrc.d/zinit.zsh" ".zshrc.d/options.zsh" ".zshrc.d/"foo"" ".zshrc.d/foo bar" ".zshrc.d/lscolors.zsh" #
Notice the file .zshrc.d/"foo"
is incorrectly escaped.
❯ echo ".zshrc.d/"foo""
.zshrc.d/foo
❯ echo '.zshrc.d/"foo"'
.zshrc.d/"foo"
Upvotes: -1
Reputation: 967
You could also simply use find "-printf", as in :
find . -printf "\"%p\" " | xargs your_command
where:
%p = file-path
This will surround every found file-path with quotes and separate each item with a space. This avoids the use of multiple commands.
Upvotes: 65
Reputation: 41
find . | sed "s|.*|\"&\"|"
Brief description:
We take result of .* pattern and put it into quotes.
Good source is sed.
Detail description:
Pattern: s/one/ONE/
Upvotes: 1
Reputation: 15952
You can use the GNU ls
option --quoting-style
to easily get what you are after. From the manual page:
--quoting-style=WORD
use quoting style
WORD
for entry names:literal
,locale
,shell
,shell-always
,shell-escape
,shell-escape-always
,c
,escape
For example, using the command ls --quoting-style=shell-escape-always
, your output becomes:
'filename1' 'filename2' 'file name with spaces' 'foldername' 'folder name with spaces'
Using --quoting-style=c
, you can reproduce your desired example exactly. However, if the output is going to be used by a shell script, you should use one of the forms that correctly escapes special characters, such as shell-escape-always
.
Upvotes: 20
Reputation: 6070
EDIT:
The following answer generate a new-line separated LIST instead of a single line.
| tr '\n' ' '
)A less mentioned method is to use -d
(--delimiter
) option of xargs
:
find . | xargs -I@ -d"\n" echo \"@\"
-I@
captures eachfind
result as@
and then we echo-ed it with quotes
With this you can invoke any commands just as you added quotes to the arguments.
$ find . | xargs -d"\n" testcli.js
[ "filename1",
"filename2",
"file name with spaces",
"foldername",
"folder name with spaces" ]
See https://stackoverflow.com/a/33528111/665507
Upvotes: 1
Reputation: 247022
for f in *; do printf "'%s' " "$f"; done; echo
Or, thanks to Gordon Davisson:
printf "'%s' " *; echo
The trailing echo
is simply to add a newline to the output.
Upvotes: 5
Reputation: 1306
this should work
find $PWD | sed 's/^/"/g' | sed 's/$/"/g' | tr '\n' ' '
EDIT:
This should be more efficient than the previous one.
find $PWD | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '
@Timofey's solution would work with a tr in the end, and should be the most efficient.
find $PWD -exec echo -n '"{}" ' \; | tr '\n' ' '
Upvotes: 33