所以我有几个目录,我只想将以“k”开头并以“g”结尾的目录名称复制到文件中。我怎么做?
答案1
和zsh
:
print -rC1 -- k*g(N/) > dirnames.txt
但请注意,由于换行符与文件名中的任何字符一样有效,这意味着您将无法区分名为 和 的两个文件k1g
和k2g
名为 的文件k1g<newline>k2g
。
您可以通过将选项添加-N
到print
.
dirs=( ${(0)"$(<dirnames.nul-delimited)"} )
然后,您可以使用或 之类的内容对生成的文件进行后处理xargs -r0a dirnames.nul-delimited some-command
。
要还包含子目录中找到的文件的名称(基本名称/ t
ail)k*g
,您可以执行以下操作:
print -rNC1 -- **/k*g(ND/:t) > dirnames.nul-delimited
请注意,例如,如果同时存在 aa/king
和文件,则它可能会有重复项。.git/king
您可以使用以下方法删除重复项:
() { print -rNC1 -- ${(u)argv} > dirnames.nul-delimited; } **/k*g(ND/:t)
获得人类可读且可后处理的文件列表的一种方法是使用 shell 引用文件名:
print -rC1 -- k*g(N/:q) > dirnames.txt
这里使用zsh
特定的引用变体。或者使用可移植的(在类似 sh 的 shell 中)和更可靠的引用语法:
() { print -rC1 -- ${(qq)argv} > dirnames.txt; } k*g(N/)
或者使用 GNU ls
:
ls -Ud --quoting-style=shell-always -- k*g(N/) > dirnames.txt
稍后可以通过以下方式检索该列表:
dirs=( ${(Q)${(zZ[n])"$(<dirnames.txt)"}} )
在zsh
。
或者在两者中zsh
或bash
(或 ksh93,如果您dirs
首先声明为数组):
eval "dirs=( $(<dirnames.txt) )"
如果您没有或zsh
由于某种原因无法使用,但在 GNU 系统上,并且您的文件名是在语言环境中的有效文本上创建的,您可以执行以下操作:
每行打印一个(假设文件名不包含换行符):
find . -mindepth 1 -maxdepth 1 -name 'k*g' -type d -printf '%f\n' | sort > dirnames.txt
相同的 NUL 分隔:
find . -mindepth 1 -maxdepth 1 -name 'k*g' -type d -printf '%f\0' | sort -z > dirnames.txt
递归,以 null 分隔:
find . -name 'k*g' -type d -printf '%f\0' | sort -z > dirnames.txt
相同的重复数据删除:
find . -name 'k*g' -type d -printf '%f\0' | LC_ALL=C sort -zu | sort -z > dirnames.txt
引用(虽然按批次排序)
find . -mindepth 1 -maxdepth 1 -name 'k*g' -type d -printf '%f\0' | xargs -r0 ls -d --quoting-style=shell-always --
引用并正确排序:
find . -mindepth 1 -maxdepth 1 -name 'k*g' -type d -printf '%f\0' | sort -z | LC_ALL=C gawk -v 'RS=\0' -v q="'" ' shquote(s) { gsub(q, q "\\" q q, s) return q s q } {print shquote($0)}' | xargs -r0 ls -d --quoting-style=shell-always --
答案2
可能最好不要使用ls
,因为这。
尝试:
find * -maxdepth 0 -type d -name 'k*g' > filename.txt
(如果没有-maxdepth 0
它,也会执行文件夹的子文件夹。如果大写的 K 和 G 也应该计算在内,请使用-iname
代替。)-name
如果您有可能拥有以连字符开头的文件夹或文件(但是谁做的?),您可以使用它:
find . -maxdepth 1 -type d -name 'k*g' | sed 's/^\.\///' > filename.txt
-maxdepth 0
注意从到 的切换-maxdepth 1
。
答案3
您可以将 shell 通配符与重定向一起使用:
$ ls -d k*g/ > filename.txt
如果您的目录名称包含换行符,这将会中断。 (我思考它只会选取目录而不是文件,但我不在计算机前进行检查。)