在特定目录中,使用ls | tee -a file.txt
给我一个来自该目录的列表。
例子:
file1.txt file2.txt file3.txt
如何将ls
命令中的特定字符串添加到最终输出中以进行批量后处理?我需要为每个文件复制并粘贴特定的文件名和特定的命令。
例子是
ls | tee -a string1(FilenameFromDirectory)string2
输出
string1(file1.txt)string2
string1(file2.txt)string2
string1(file3.txt)string2
答案1
在开头和结尾添加字符串非常简单:
$ ls
file1.txt file2.txt file3.txt
$ ls | sed -e 's/^/string1/' -e 's/$/string2/'
string1file1.txtstring2
string1file2.txtstring2
string1file3.txtstring2
我强烈建议您不要使用括号( )
。文件名中包含特殊字符会使处理更加复杂。如果可以的话,使用_
or代替。-
如果你坚持使用括号,你可以这样做:
$ ls | sed -e 's/^/string1(/' -e 's/$/)string2/'
string1(file1.txt)string2
string1(file2.txt)string2
string1(file3.txt)string2
重要的:如果您只想在终端中打印结果或按照您所做的>
那样发送到文件,这是可以的。tee
但是,如果你想用它来重命名、复制或以其他方式处理文件,那就不行了,因为解析ls
这种方式非常脆弱,甚至会因为稍微奇怪的文件名而崩溃。更安全的方法是:
$ for file in *; do
printf 'string1(%s)string2\n' "$file"
done
string1(file1.txt)string2
string1(file2.txt)string2
string1(file3.txt)string2
答案2
printf 'string1(%s)string2\n' *
将为string1(filename)string2
当前工作目录中的每个非隐藏文件打印一行,按词法排序,或者如果没有匹配的文件则失败并显示错误。
当没有匹配文件时不打印任何内容,而不是报告错误,可以通过使用N
(nullglob) glob 限定符并检查文件数来完成:
files=( *(N) )
(( $#files == 0 )) || printf 'string1(%s)string2\n' $files
或者使用匿名函数和 rc 风格的数组扩展:
() { print -rC1 'string1('$^files')string2'; } *(N)
但如果你想为每个文件运行一些命令,你可以这样做:
for file (*(N)) cmd with $file as argument
要将这些命令/循环的输出发送到原始 stdout 并将其附加到某个文件,您可以将它们通过管道传递到tee -a some-file
或仅在输出重定向多次时添加>&1 >> some-file
wherezsh
不是隐式内置函数。tee