我有五个目录 Dir1、Dir2、Dir3、Dir4、Dir5。在每个目录中,我有五个包含数据的文本文件(分别命名为 file1.txt、file2.tx、.file5.txt)。我想要的是从所有五个目录复制 file1.txt 并将它们依次附加到不同的目录(名为 Joint_Dir)中。对 file2.txt、file3.txt...file5.txt 执行相同操作。
答案1
你可以这样做通配符模式/通配符。例如,以下命令会将目录file1.txt
中的所有文件连接到一个文件中Joint_Dir
:
cat Dir[1-5]/file1.txt > Joint_Dir/file1.txt
但在使用模式匹配执行这样的命令之前,我会运行几个健全性检查命令来验证哪些文件将受到影响。在这种情况下,您可以使用以下命令检查模式是否Dir[1-5]/file1.txt
与预期文件匹配ls
:
ls -ld Dir[1-5]/file1.txt
另一种选择是使用大括号扩展。使用大括号扩展重写前面的示例会产生以下结果:
cat Dir{1..5}/file1.txt > Joint_Dir/file1.txt
请注意,大括号扩展是所谓的巴什主义并且可能无法在不同的 shell 中工作。这种区别已在其他地方讨论过,例如大括号扩展在脚本中不起作用。正如该文章中所讨论的,其他替代方案包括使用seq
命令或在 while 循环内递增变量。
说到循环,如果您想在单个命令中执行所有串联,您可以使用 for 循环,例如:
for i in $(seq 1 5); do
cat Dir[1-5]/file${i}.txt > Joint_Dir/file${i}.txt
done
下面是一个独立的示例,说明如何使用上述技术。您应该能够按原样运行以下命令。首先,这是一个脚本,用于设置一个目录,其中包含测试文件,镜像原始问题中所描述的内容:
#!/bin/bash
# create-test-files.sh
# Create test files and directories
for i in $(seq 1 5); do
mkdir -p "/tmp/test/Dir${i}"
for j in $(seq 1 5); do
echo "File ${j} in directory ${i}" > "/tmp/test/Dir${i}/file${j}.txt"
done
done
运行此脚本后,我们可以检查刚刚创建的内容:
$ bash create-test-files.sh
$ tree /tmp/test/
/tmp/test/
|-- Dir1
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| `-- file5.txt
|-- Dir2
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| `-- file5.txt
|-- Dir3
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| `-- file5.txt
|-- Dir4
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| `-- file5.txt
`-- Dir5
|-- file1.txt
|-- file2.txt
|-- file3.txt
|-- file4.txt
`-- file5.txt
5 directories, 25 files
我们还可以检查文件的内容:
$ cat /tmp/test/Dir[1-5]/file1.txt
File 1 in directory 1
File 1 in directory 2
File 1 in directory 3
File 1 in directory 4
File 1 in directory 5
$ cat /tmp/test/Dir1/file[1-5].txt
File 1 in directory 1
File 2 in directory 1
File 3 in directory 1
File 4 in directory 1
File 5 in directory 1
接下来我们可以创建以下脚本来连接文件:
#!/bin/bash
# concatenate-test-files.sh
# Create output directory
mkdir -p /tmp/test/Joint_Dir
# Concatenate identically-named files from different directories
for i in $(seq 1 5); do
cat "/tmp/test/Dir"[1-5]"/file${i}.txt" > "/tmp/test/Joint_Dir/file${i}.txt"
done
运行此脚本后,我们可以检查输出目录的内容:
$ bash concatenate-test-files.sh
$ ls -1 /tmp/test/Joint_Dir/
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
$ cat /tmp/test/Joint_Dir/file1.txt
File 1 in directory 1
File 1 in directory 2
File 1 in directory 3
File 1 in directory 4
File 1 in directory 5
完成实验后,我们可以删除测试目录:
rm -rf /tmp/test