[英]bash: use list of file names to concatenate matching files across directories and save all files in new directory
I have a large number of files that are found in three different directories.我在三个不同的目录中找到了大量文件。 For some of these files, a file with an identical name exists in another directory.
对于其中一些文件,另一个目录中存在具有相同名称的文件。 Other files exist in only one directory.
其他文件只存在于一个目录中。 I'd like to use bash to copy all of the files from the three directories to a single new directory, but for files with identically named files in more than one directory I want to concatenate the file contents across directories before saving to the new directory.
我想使用 bash 将三个目录中的所有文件复制到一个新目录中,但是对于在多个目录中具有相同名称文件的文件,我想在保存到新目录之前将文件内容跨目录连接起来.
Here's an example of what my file structure looks like:这是我的文件结构的示例:
ls dir1/
file1.txt
file2.txt
file4.txt
ls dir2/
file2.txt
file5.txt
file6.txt
file9.txt
ls dir3/
file2.txt
file3.txt
file4.txt
file7.txt
file8.txt
file10.txt
Using this example, I'd like to produce a new directory that contains file1.txt through file10.txt, but with the contents of identically named files (eg file2.txt, file4.txt) concatenated in the new directory.使用此示例,我想生成一个包含 file1.txt 到 file10.txt 的新目录,但在新目录中连接了同名文件(例如 file2.txt、file4.txt)的内容。
I have a unique list of all of the file names contained in my three directories (single instance of each unique file name is contained within the list).我有一个包含在我的三个目录中的所有文件名的唯一列表(列表中包含每个唯一文件名的单个实例)。 So far, I have come up with code to take a list of file names from one directory and concatenate these files with identically named files in a second directory, but I'm not sure how to use my list of file names as a reference for concatenating and saving files (instead of the output from ls in the first directory).
到目前为止,我已经想出了代码来从一个目录中获取文件名列表,并将这些文件与第二个目录中的同名文件连接起来,但我不确定如何使用我的文件名列表作为参考连接和保存文件(而不是第一个目录中 ls 的输出)。 Any ideas for how to modify?
关于如何修改的任何想法? Thanks very much!
非常感谢!
PATH1='/path/to/dir1'
PATH2='/path/to/dir2'
PATH3='/path/to/dir3'
mkdir dir_new
ls $PATH1 | while read FILE; do
cat $PATH1/"$FILE" $PATH2/"$FILE" $PATH3/"$FILE" >> ./dir_new/"$FILE"
done
You can do it like this:你可以这样做:
mkdir -p new_dir
for f in path/to/dir*/*.txt; do
cat "$f" >> "new_dir/${f##*/}"
done
This is a common use for substring removal with parameter expansion, in order to use only the basename of the file to construct the output filename.这是通过参数扩展删除子字符串的常见用途,以便仅使用文件的基本名称来构造输出文件名。
Or you can use a find
command to get the files and execute the command for each one:或者您可以使用
find
命令来获取文件并为每个文件执行命令:
find path/to/dir* -type f -name '*.txt' -print0 |\
xargs -0 -n1 sh -c 'cat "$0" >> new_dir/"${0##*/}"'
In the above command, the filenames out of find
are preserved with zero separation ( -print0
), and xargs
also accepts a zero separated list ( -0
).在上面的命令中,
find
的文件名以零分隔( -print0
)保留,并且xargs
也接受零分隔列表( -0
)。 For each argument ( -n1
) the command following is executed.对于每个参数 (
-n1
),将执行以下命令。 We call sh -c 'command'
for convenience to use the substring removal inside there, we can access the argument provided by xargs
as $0
.我们调用
sh -c 'command'
为了方便在那里使用子字符串删除,我们可以将xargs
提供的参数访问为$0
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.