我有一个包含一长串文件名(带有完整路径)的文件。我还有一个我想多次运行的程序,使用此列表中的一个和一个文件名作为参数。我想运行的程序很遗憾是一个自制的脚本;所以它一次只能取一个文件名,并且它不能接受来自stdin 的输入(如文件名列表)——所以不可能进行管道或输入重定向。
我需要的是一个命令,它将运行另一个命令(我的脚本),使用文件中的行作为参数。
喜欢的东西find与-exec-action ...( find . -name "*.txt" -exec command \;)。我想我实际上可以find在这里使用,但我希望对输入文件进行排序......
所以我需要的是这样的:
for_each_command1 -f list_of files -c './my_command {}'
for_each_command2 -f list_of_files -exec ./my_command {} \;
for_each_command3 -c './my_command {}'
我处理此类任务的常用方法是sed- 不幸的是,有很多开销而且它并不漂亮(但它确实有效......):
$ wc -l list_of_files
232
$ for (( i=1; 我愿意
> ./my_command "`sed -n "${i}p" list_of_files`"
> 完成
那么是否有内置的命令或 shell 来处理这样的事情?
假设我们有 4 个文件:
a.zip created on 28 feb 2018
b.zip created on 28 feb 2018
c.zip created on 2 mar 2018
d.zip created on 2 mar 2018
Run Code Online (Sandbox Code Playgroud)
我想搜索 28 Feb 的文件并将其压缩。
find ./ -type f -ls | grep 'Feb 28' | tar -czf somefile3.tar --null -T -
Run Code Online (Sandbox Code Playgroud)
但它不起作用。
我有一个文件夹,我将数据库备份到其中,我想删除在上午 11 点到下午 3 点之间创建的所有备份,不管是哪一天——这就是问题所在!
我发现此命令非常有用,但不适用于我的用例:
find . -type f -newermt '01 nov 2018 00:00:00' -not -newermt '10 nov 2018 00:00:00' -delete
Run Code Online (Sandbox Code Playgroud)
但在这里它迫使我在两个日期之间间隔一段时间!我只想删除在两个特定时间之间创建的备份。
我正在尝试对齐 bashfor循环的输出。
目前,我从循环中得到如下输出:
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
Run Code Online (Sandbox Code Playgroud)
我试图这样对齐:
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
Run Code Online (Sandbox Code Playgroud)
生成此输出的当前基本循环如下所示:
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
Run Code Online (Sandbox Code Playgroud)
我试过使用:
column (分别格式化每一行,因为它是一个 for 循环)printf ( printf "Directory: %s Remote: %s\n" "$dir" "$remote")awk( echo "Directory: $dir Remote: $remote" | awk '{printf ("%s-20s %s-20s %s-20s %s-20s",$1 $2 $3 $4)}')在这些命令的许多其他变体中。
我可能缺少一些基本的东西(我尽力在网上查看其他示例并阅读man页面),但我无法让它工作。
我真的很感激任何关于我做错了什么的指示。
我有一个场景,我循环遍历给定路径中的所有目录和子目录;如果找到具有特定扩展名 (.txt) 的文件,则将目录和子目录的名称存储在数组中。后来,我在这些目录上读取并执行命令。
这是我正在执行的操作:
!/bin/bash
x=( $(find . -name "*.txt") ); echo "${x[@]}"
for item in "${x[@]}"; { echo "$item"; }
Run Code Online (Sandbox Code Playgroud)
我当前的输出是:
./dir1/file1.txt
./dir1/file2.txt
./dir2/subdir1/subdir2/file3.txt
Run Code Online (Sandbox Code Playgroud)
但我想要实现的是,x即使目录包含多个.txt文件,数组中也不应该有任何重复项。此外,我不想将文件名存储为路径;该数组应仅包含目录名称。
预期输出:
./dir1
./dir2/subdir1/subdir2/
Run Code Online (Sandbox Code Playgroud) 以下链接建议不要在 shell 中使用循环。
为什么是这样?这是我在遇到该答案时碰巧正在查看的示例循环:
find /etc/postinstall -name '*.sh' | while read script
do
echo Running $script ...
$script
mv $script $script.done
done
Run Code Online (Sandbox Code Playgroud) 当我执行以下命令时:
#!/bin/bash
while IFS= read -r -d '' file; do
files+=$file
done < <(find -type f -name '*.c' -print0)
echo "${files[@]}"
Run Code Online (Sandbox Code Playgroud)
我没有得到与此相同的结果:
#!/bin/bash
find_args="-type f '*.c' -print0"
while IFS= read -r -d '' file; do
files+=$file
done < <(find $find_args)
echo "${files[@]}"
Run Code Online (Sandbox Code Playgroud)
如何将第二个场景修复为与第一个相同?
我的理解是,因为双引号中有单引号,单引号会被转义,这会产生一个糟糕的扩展,看起来像这样:
find -type f -name ''\''*.c'\'' -print0
Run Code Online (Sandbox Code Playgroud) Ubuntu 16.04
#!/bin/bash
site="hello"
wDir="/home/websites/${site}/httpdocs/"
for file in $(find "${wDir}" -name "*.css")
do
echo "$file";
done
exit 0;
Run Code Online (Sandbox Code Playgroud)
即使我定义了开始目录,shellcheck 也会警告我,但脚本工作得很好。
root@me /scripts/ # shellcheck test.sh
In test.sh line 6:
for file in $(find "${wDir}" -name "*.css")
^-- SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
Run Code Online (Sandbox Code Playgroud) 使用时find,如何.pdf从第二对-exec大括号 ( {}) 中删除原始文件扩展名 (即)?
例如:
find ~/Documents -regex 'LOGIC.*\.pdf' -exec pdf2svg {} {}.svg \;Run Code Online (Sandbox Code Playgroud)
输入文件名:
~/Documents/LOGIC-P_OR_Q.pdfRun Code Online (Sandbox Code Playgroud)
输出文件名:
~/Documents/LOGIC-P_OR_Q.pdf.svgRun Code Online (Sandbox Code Playgroud)
所需文件名:
~/Documents/LOGIC-P_OR_Q.svgRun Code Online (Sandbox Code Playgroud) 我正在尝试在输出上运行 sedfind | grep \.ext$
但是,sed 需要输入文件和输出文件。
如何将输出行保存到变量,或将其传递给 sed?