Bash:遍历文本文件中列出的文件并移动它们
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6566591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash: Loop over files listed in a text file and move them
提问by PatentDeathSquad
I have a directory (directory A) with 10,000 files in it. I want to move some of them to directory B and the others to directory C. I made a text file that contains the names of all the files I want to move to directory B and another one with the names of all the files that I want to move to directory C. How can I write a bash for loop to move these files to the new directories.
我有一个包含 10,000 个文件的目录(目录 A)。我想将其中一些移动到目录 B,其他移动到目录 C。我制作了一个文本文件,其中包含要移动到目录 B 的所有文件的名称,另一个包含我想要的所有文件的名称移动到目录 C。我如何编写一个 bash for 循环来将这些文件移动到新目录。
Pseudocode:
伪代码:
for file in textfileB:
move file from directory A to directory B
对于 textfileB 中的文件:
将文件从目录 A 移动到目录 B
for file in textfileC:
move file from directory A to directory C
对于 textfileC 中的文件:
将文件从目录 A 移动到目录 C
Sorry if this is asked somewhere else, but I've spent hours trying to learn bash and I just don't get it. I wasn't able to find something similar enough in another thread that I could understand (maybe I just don't know the right search words).
抱歉,如果在其他地方有人问过这个问题,但我花了几个小时试图学习 bash,但我就是不明白。我无法在另一个我能理解的线程中找到足够相似的内容(也许我只是不知道正确的搜索词)。
I got something like this, but I couldn't get it working:
我得到了这样的东西,但我无法让它工作:
FILES=[dont' know what goes here? An array? A list?
Can I just state the text file name and if so what format do the files have to be? name1.ext, name2.ext, or name1.ext name2.ext]
我可以只说明文本文件名吗?如果可以,文件必须是什么格式?name1.ext、name2.ext 或 name1.ext name2.ext]
for f in $FILES; do mv $f /B/$f [not sure about the second argument for mv]; done
thx
谢谢
BTW Mac OSX 10.6.8 (Snow Leopard) Apple Terminal v. 2.1.2 / 273.1 Bash 3.2
BTW Mac OSX 10.6.8 (Snow Leopard) Apple Terminal v. 2.1.2 / 273.1 Bash 3.2
回答by asveikau
cat file-list.txt | while read i; do
# TODO: your "mv" command here. "$i" will be a line from
# the text file.
done
回答by Ignacio Vazquez-Abrams
BASH 常见问题条目 #1:“如何逐行(和/或逐字段)读取文件(数据流、变量)?”
If the filename will remain the same then the second argument to mvcan be just the directory.
如果文件名保持不变,则第二个参数mv可以只是目录。
回答by Vijay
directory of the script should be the your location of the files
脚本的目录应该是您的文件位置
TO_B=file1.txt
TO_C=file2.txt
for file in $TO_B
do
mv ${file} B/
done
for file in $TO_C
do
mv ${file} C/
done
回答by Laxman Singh
you can move 1000 or 1000 user directory without take much time where thousand of user directory exist.
您可以移动 1000 或 1000 个用户目录,而无需花费太多时间在存在数千个用户目录的情况下。
cat deleteduser | while read i; do mv -vv $i ../deleted_user; done;
deleteuser= user name list
../deleted_user= destination dir
回答by anon
Using bash, having a huge filelist containing strings with leading and/or closing spaces I'd propose:
使用 bash,有一个巨大的文件列表,其中包含带有前导和/或关闭空格的字符串,我建议:
less 'file-list.txt' | while read -r; do mv "$REPLY" /Volumes/hard_drive_name/new_destination_directory_name; done
see:
看:
回答by David W.
You have to use BASH? What about Perl or Kornshell? The problem here is that Bash doesn't have hash keyed arrays (Kornshell and Perl do). That means there's no simple way to track what files go where. Imagine in Perl:
你一定要用BASH吗?Perl 或 Kornshell 怎么样?这里的问题是 Bash 没有散列键控数组(Kornshell 和 Perl 有)。这意味着没有简单的方法来跟踪哪些文件去了哪里。在 Perl 中想象一下:
my %directoryB; #Hash that contains files to move to Directory B
my %directoryC; #Hash that contains files to move to Directory C
open (TEXT_FILE_B, "textFileB") or die qq(Can't open "textFileB");
while (my $line = <TEXT_FILE_B>) {
chomp $line;
$directoryB{$line} = 1;
}
close TEXT_FILE_B;
open (TEXT_FILE_C, "textFileC") or die qq(Can't open "textFileC");
while (my $line = <TEXT_FILE_C>) {
chomp $line;
$directoryC{$line} = 1;
}
close TEXT_FILE_C;
The above lines create two hashes. One for files that need to be moved to Directory B and one for files that need to be moved to Directory C. Now, all I have to do is look at my hash and decide:
以上几行创建了两个哈希。一个用于需要移动到目录 B 的文件,另一个用于需要移动到目录 C 的文件。现在,我所要做的就是查看我的哈希值并决定:
foreach my $file (@directory) { #A little cheating here...
if (exists $directoryB{$file}) {
move ($file, $directoryB);
} elsif (exists $directoryC{$file}) {
move ($file, $directoryC)
}
My if statements can now look to see if a key has been defined in that hash. If it has, I know the file can be moved into that directory. I only have to read the two text files once. After that, my two hashes will store which files move to one directory and which to the other.
我的 if 语句现在可以查看是否在该散列中定义了一个键。如果有,我知道可以将文件移动到该目录中。我只需要阅读这两个文本文件一次。之后,我的两个散列将存储哪些文件移动到一个目录,哪些文件移动到另一个。
However, we don't have hashes, so we'll use grepto see if the file name is in the directory. I'll assume that you have one file name on each line.
但是,我们没有哈希值,因此我们将使用它grep来查看文件名是否在目录中。我假设每一行都有一个文件名。
ls | while read file
do
if grep -q "^${file}$" textFileB
then
mv $file $directoryB
elif grep -q "^${file}$" textFileC
then
mv $file $directoryC
fi
done
The grep -qwill search your two text files to see if the matching file is there. If it is, it'll move the file to that directory. It's not very efficient since it has to search the entire text file each and every time. However, it's pretty efficient, and you're only talking about 10,000 files, so the whole operation should only take a few minutes.
该grep -q会搜索你的两个文本文件,看看是否匹配的文件是存在的。如果是,它会将文件移动到该目录。它不是很有效,因为它每次都必须搜索整个文本文件。但是,它非常有效,而且您只是在谈论 10,000 个文件,因此整个操作应该只需要几分钟。

