Bash 如何在单行中输出带引号的文件名?
我想按以下方式输出文件夹中的项目列表:Bash 如何在单行中输出带引号的文件名?,bash,unix,find,xargs,Bash,Unix,Find,Xargs,我想按以下方式输出文件夹中的项目列表: "filename1" "filename2" "file name with spaces" "foldername" "folder name with spaces" 换句话说,项目名称必须在一行中,用引号(单引号或双引号)包围,并用空格分隔 我知道 find . | xargs echo 在一行中打印输出,但我不知道如何在每个项目名称周围添加引号 此代码是bsh脚本的一部分。 因此,解决方案可以是一组命令,并使用临时文件来存储中间输出 非常感
"filename1" "filename2" "file name with spaces" "foldername" "folder name with spaces"
换句话说,项目名称必须在一行中,用引号(单引号或双引号)包围,并用空格分隔
我知道
find . | xargs echo
在一行中打印输出,但我不知道如何在每个项目名称周围添加引号
此代码是bsh脚本的一部分。
因此,解决方案可以是一组命令,并使用临时文件来存储中间输出
非常感谢你的建议
干杯,安娜试试这个
find . -exec echo -n '"{}" ' \;
这应该行得通
find $PWD | sed 's/^/"/g' | sed 's/$/"/g' | tr '\n' ' '
编辑:
这应该比前一个更有效
find $PWD | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '
@蒂莫菲的解决方案最终将与tr一起使用,并且应该是最有效的
find $PWD -exec echo -n '"{}" ' \; | tr '\n' ' '
或者,多亏了:
尾随的
echo
只是向输出添加一个换行符。您也可以简单地使用find“-printf”,如下所示:
其中:
%p = file-path
这将用引号围绕找到的每个文件路径,并用空格分隔每个项目。
这避免了使用多个命令。编辑:下面的答案生成一个新的行分隔列表,而不是一行
|tr'\n'
)较少提及的方法是使用
xargs
的-d
(--delimiter
)选项:
find . | xargs -I@ -d"\n" echo \"@\"
-I@
将每个查找
结果捕获为@
,然后用引号将其回显
这样,您就可以在为参数添加引号时调用任何命令
$ find . | xargs -d"\n" testcli.js
[ "filename1",
"filename2",
"file name with spaces",
"foldername",
"folder name with spaces" ]
请参见您可以使用GNU
ls
选项--quoting style
轻松获取所需内容。从手册页面:
--quoting style=WORD
对条目名称使用引用样式WORD
:literal
,locale
,shell
,shell始终
,shell转义始终
,c
,escape
例如,使用命令ls--quoting style=shell escape always,您的输出变成:
'filename1' 'filename2' 'file name with spaces' 'foldername' 'folder name with spaces'
使用--quoting style=c
,您可以准确地重现所需的示例。但是,如果输出将由shell脚本使用,则应使用正确转义特殊字符的表单之一,例如shell转义始终
try
ls | sed -e 's/^/"/g' -e 's/$/"/g' | tr '\n' ' '
简要说明:我们将。*模式的结果放入引号中。
好的来源是。
详细说明:
模式:s/one/one/
- s替换命令
- /分隔符。
在我的表达式中,使用“|”而不是“/”来防止像s/*/\“&\”模式中的“山” - one正则表达式模式搜索模式
- 一个替换字符串
- *表示任何重复次数不限的符号
- \“表示”本身
- &与找到的模式对应的特殊字符
printf
s%q
格式选项:
❯ 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:
请注意,文件.zshrc.d/“foo”
的转义错误
❯ echo ".zshrc.d/"foo""
.zshrc.d/foo
❯ echo '.zshrc.d/"foo"'
.zshrc.d/"foo"
10年后,没有人提出Bash“while read”方法 这是一个简单的bashshell管道,而不是启动另一个程序,如sed或xarg。如果确实要对每个文件/文件夹执行某些操作:
find * -type d -depth 0|while read f; do du -sh "$f"; done
顺便说一句,
find*
使用了另一个Bash功能,它排除了.xyz文件/文件夹,并且不会输出/
前缀find.
确实如此。这非常有效!非常感谢你。现在,我的最后一个命令是:“find.!-typel(-name.-o-prune)| sort-n | sed's/^/“/g'| sed's/$/”/g'| tr'\n''| xargs myCommand”。这一行是myCommand的输入参数。请,请不要。首先,find$PWD
如果您的$PWD
包含空格或文本全局字符,并且这些字符可以扩展为任何内容,那么它将表现得很差。其次,用双引号替换名称以试图转义它是一种脆弱且容易规避的机制——有效的文件名本身可以包含“
或”
字符,从而中断对整个流其余部分的解析。@Ana,如果在使用GNU工具的系统上(find-print0
和sort-z
),最好使用find…-print0 | sort-n-z | xargs-0 myCommand
@Ana,…即使您不想使用NUL分隔符,您仍然可以告诉xargs
仅使用换行分隔符,并对带有空格的文件名保持安全(虽然不是带换行符的文件名,但您已经接受的答案对于包含换行符的文件名也已经不安全):find…| sort-n | xargs-d$'\n'myCommand
您确实应该使用“ls”来列出目录内容。它确实有必要的选项。这可以进一步简化:printf''%s'*
.remove-n以获得包含换行符的结果。在Solaris 11上不起作用,只打印-n“{}”
很多次!如果目标是将带空格的名称传递给xargs,则使用文字引号是错误的方式。这应该标记为正确答案。regex操作级别太低。我必须在Windows上使用cygwin添加新行,以使输出相同:-printf“\%p\”\n
-printf在OSX上不可用。@Nimrod With Homebrew:brew安装findutils--使用默认名称
…如果文件名包含引号,则会显著失败。相关:“ls-Q”#添加双引号我建议:ls-1--quoting style=c
find . | sed "s|.*|\"&\"|"
❯ 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 #
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" #
❯ echo ".zshrc.d/"foo""
.zshrc.d/foo
❯ echo '.zshrc.d/"foo"'
.zshrc.d/"foo"
find * -type d -depth 0|while read f; do echo \"$f\"; done
find * -type d -depth 0|while read f; do du -sh "$f"; done