how to output file names surrounded with quotes in SINGLE line?
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 mu开发者_如何学运维st 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
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.
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' ' '
Try this.
find . -exec echo -n '"{}" ' \;
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
.
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.
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.
EDIT:
The following answer generate a new-line separated LIST instead of a single line.
- I'm second guessing that the OP uses the result for invoking other command
- converting the output LIST to single line is easy (
| 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
try
ls | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '
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/
- s Substitute command.
- / Delimiter.
In my expression "|" is used instead of "/" to prevent "mountains" like in pattern s/.*/\"&\"/. - one Regular expression pattern search pattern.
- ONE Replacement string.
- .* Means any symbol that repeats unlimited number of times.
- \" Means " itself.
- & Special character that corresponds to the pattern found.
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.
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"
精彩评论