如何逐行读出文件并为每一行使用 find 进行搜索并将搜索结果复制到目标?
How to read out a file line by line and for every line do a search with find and copy the search result to destination?
希望你能帮我解决以下问题:
情况
- 我需要在各个文件夹中找到文件并将它们复制到另一个文件夹中。文件和文件夹可以包含空格和变音符号。
- 文件名包含一个 ID 和一个字符串,例如:
“2022-01-11-02 超级重要文件”
- 我需要查找的文件名收集在名为 ids.txt 的文本文件中。此文件仅包含 ID 而不是字符串形式的整个文件名。
我想达到的效果:
- 我要逐行读出ids.txt。
- 对于 ids.txt 中的每一行,我想进行
find
搜索并将结果复制 cp
到目的地。
到目前为止我试过:
for n in $(cat ids.txt); do find /home/alex/testzone/ -name "$n" -exec cp {} /home/alex/testzone/output \; ;
while read -r ids; do find /home/alex/testzone -name "$ids" -exec cp {} /home/alex/testzone/output \; ; done < ids.txt
输出文件夹仍然是空的。不使用 -exec
也没有(搜索)结果。
我在想 -name "$ids"
是这里的根本原因。我的文件包含 ID + 字符串,所以我应该搜索包含 ID 加上 可变字符串(星号)
的名称
- 作为
-name
的论据,我也尝试了 "$ids *"
"$ids"" *"
等等,但没有成功。
有没有我可以与 find 一起使用的参数,而不是在 -name
参数中使用星号?
你有什么解决方案可以让我在 bash 脚本中自动执行此过程以读出 ids.txt 文件、搜索文件名并将它们复制到指定文件夹吗?
最后我想创建一个 bash 脚本,它将 ids.txt 和搜索文件夹和输出文件夹作为参数,例如:
my-id-search.sh /home/alex/testzone/ids.txt /home/alex/testzone/ /home/alex/testzone/output
编辑:
这是 ids.txt 文件的一些示例内容,其中仅列出了 ID(不是整个文件名):
2022-01-11-01
2022-01-11-02
2020-12-01-62
编辑二:
继续使用 tripleee 的解决方案:
#!/bin/bash
grep . | while read -r id; do
echo "Der Suchbegriff lautet:"$id; echo;
find /home/alex/testzone -name "$id*" -exec cp {} /home/alex/testzone/ausgabe \;
done
如果我的 ids.txt 文件包含空行,-name "$id*"
将是 -name *
,这反过来会找到所有文件并复制所有文件。
试图阻止空行被读取似乎不起作用。它们应该通过表达式 grep . |
进行过滤。我做错了什么?
请尝试以下 bash 脚本 copier.sh
#!/bin/bash
IFS=$'\n' # make newlines the only separator
set -f # disable globbing
file="files.txt" # name of file containing filenames
finish="finish" # destination directory
while read -r n ; do (
du -a | awk '{for(i=2;i<=NF;++i)printf $i" " ; print " "}' | grep $n | sed 's/ *$//g' | xargs -I '{}' cp '{}' $finish
);
done < $file
它递归地从 .它是 ./finish 的子文件
即使目录名或文件名中有空格,这个新版本也能正常工作。
如果您的目标文件夹始终相同,最快且绝对最优雅的解决方案是 运行 一个 find
命令来查找所有文件。
sed 's/.*/-o\n—name\n&*/' ids.txt |
xargs -I {} find -false {} -exec cp {} /home/alex/testzone/output +
-false
谓词允许 actual 谓词列表以 -o
开头(如“或”) .
如果 ids.txt
太大而无法放入单个 xargs
调用,或者如果您的 sed
不理解 \n
的意思是文字换行符,这可能会失败.
(这是对后一种情况的修复:
xargs printf '-o\n-name\n%s*\n' <ids.txt |
...
仍然像这样使用 xargs find
的内在问题是 xargs
可以将列表拆分为 -o
和 -name
或 -name
和实际文件名模式,如果它需要 运行 多个 find
命令来处理所有参数。)
一个更普通的解决方案通过在 -name
参数中添加缺少的通配符来修复您的 while read
尝试。 (我还冒昧地重命名了变量,因为 read
一次只会读取一个参数,所以变量名应该是单数。)
while read -r id; do
find /home/alex/testzone -name "$id*" -exec cp {} /home/alex/testzone/output \;
done < ids.txt
希望你能帮我解决以下问题:
情况
- 我需要在各个文件夹中找到文件并将它们复制到另一个文件夹中。文件和文件夹可以包含空格和变音符号。
- 文件名包含一个 ID 和一个字符串,例如: “2022-01-11-02 超级重要文件”
- 我需要查找的文件名收集在名为 ids.txt 的文本文件中。此文件仅包含 ID 而不是字符串形式的整个文件名。
我想达到的效果:
- 我要逐行读出ids.txt。
- 对于 ids.txt 中的每一行,我想进行
find
搜索并将结果复制cp
到目的地。
到目前为止我试过:
for n in $(cat ids.txt); do find /home/alex/testzone/ -name "$n" -exec cp {} /home/alex/testzone/output \; ;
while read -r ids; do find /home/alex/testzone -name "$ids" -exec cp {} /home/alex/testzone/output \; ; done < ids.txt
输出文件夹仍然是空的。不使用 -exec
也没有(搜索)结果。
我在想 -name "$ids"
是这里的根本原因。我的文件包含 ID + 字符串,所以我应该搜索包含 ID 加上 可变字符串(星号)
- 作为
-name
的论据,我也尝试了"$ids *"
"$ids"" *"
等等,但没有成功。
有没有我可以与 find 一起使用的参数,而不是在 -name
参数中使用星号?
你有什么解决方案可以让我在 bash 脚本中自动执行此过程以读出 ids.txt 文件、搜索文件名并将它们复制到指定文件夹吗?
最后我想创建一个 bash 脚本,它将 ids.txt 和搜索文件夹和输出文件夹作为参数,例如:
my-id-search.sh /home/alex/testzone/ids.txt /home/alex/testzone/ /home/alex/testzone/output
编辑: 这是 ids.txt 文件的一些示例内容,其中仅列出了 ID(不是整个文件名):
2022-01-11-01
2022-01-11-02
2020-12-01-62
编辑二: 继续使用 tripleee 的解决方案:
#!/bin/bash
grep . | while read -r id; do
echo "Der Suchbegriff lautet:"$id; echo;
find /home/alex/testzone -name "$id*" -exec cp {} /home/alex/testzone/ausgabe \;
done
如果我的 ids.txt 文件包含空行,-name "$id*"
将是 -name *
,这反过来会找到所有文件并复制所有文件。
试图阻止空行被读取似乎不起作用。它们应该通过表达式 grep . |
进行过滤。我做错了什么?
请尝试以下 bash 脚本 copier.sh
#!/bin/bash
IFS=$'\n' # make newlines the only separator
set -f # disable globbing
file="files.txt" # name of file containing filenames
finish="finish" # destination directory
while read -r n ; do (
du -a | awk '{for(i=2;i<=NF;++i)printf $i" " ; print " "}' | grep $n | sed 's/ *$//g' | xargs -I '{}' cp '{}' $finish
);
done < $file
它递归地从 .它是 ./finish 的子文件 即使目录名或文件名中有空格,这个新版本也能正常工作。
如果您的目标文件夹始终相同,最快且绝对最优雅的解决方案是 运行 一个 find
命令来查找所有文件。
sed 's/.*/-o\n—name\n&*/' ids.txt |
xargs -I {} find -false {} -exec cp {} /home/alex/testzone/output +
-false
谓词允许 actual 谓词列表以 -o
开头(如“或”) .
如果 ids.txt
太大而无法放入单个 xargs
调用,或者如果您的 sed
不理解 \n
的意思是文字换行符,这可能会失败.
(这是对后一种情况的修复:
xargs printf '-o\n-name\n%s*\n' <ids.txt |
...
仍然像这样使用 xargs find
的内在问题是 xargs
可以将列表拆分为 -o
和 -name
或 -name
和实际文件名模式,如果它需要 运行 多个 find
命令来处理所有参数。)
一个更普通的解决方案通过在 -name
参数中添加缺少的通配符来修复您的 while read
尝试。 (我还冒昧地重命名了变量,因为 read
一次只会读取一个参数,所以变量名应该是单数。)
while read -r id; do
find /home/alex/testzone -name "$id*" -exec cp {} /home/alex/testzone/output \;
done < ids.txt