开发者

how to output file names surrounded with quotes in SINGLE line?

开发者 https://www.devze.com 2023-03-06 12:40 出处:网络
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\"

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.

  1. I'm second guessing that the OP uses the result for invoking other command
  2. 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 each find 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 printfs %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"
0

精彩评论

暂无评论...
验证码 换一张
取 消