gpt4 book ai didi

bash - 将大量文件通过管道传输到标准输入,提取第一列,然后将它们合并到一个新文件中

转载 作者:行者123 更新时间:2023-11-29 08:57:23 27 4
gpt4 key购买 nike

假设我们有这两个文件:

$ cat ABC.txt 
ABC DEF

$ cat PQR.txt
PQR XTZ

我们想用每个文件的第一列组成一个文件。这可以通过以下方式实现:

$ paste -d ' ' <(cut -d ' ' -f 1 ABC.txt) <(cut -d ' ' -f 1 PQR.txt )
ABC PQR

但我想将它用于输入中的大量文件,不仅是 ABC.txt 和 PQR.TXT,还有很多。我们如何概括这种情况以将集合中的每个文件传递给剪切,然后将所有输出传递给粘贴(我知道使用可能会做得更好awk 但我想知道如何使用这种方法解决这个问题)。


编辑 1

我发现了一种肮脏的方法:

$ str='';  for i in *.txt; \
do str="${str} <(cut -d ' ' -f 1 ${i})"; \
done ; \
str="paste -d ' ' $str"; \
eval $str

但是请用一个不涉及计算机科学 hell 的答案释放我的灵魂。

编辑 2

如果重要的话,每个文件可以有 n 行。

最佳答案

进程替换 <(somecommand)不通过管道传输到标准输入,它实际上在一个单独的文件描述符上打开一个管道,例如63,并传入/dev/fd/63 .当这个"file"被打开时,内核*复制 fd 而不是打开一个真实的文件。

我们可以通过打开一堆文件描述符然后将它们传递给命令来做类似的事情:

# Start subshell so all files are automatically closed
(
fds=()
n=0
# Open a new fd for each process subtitution
for file in ./*.txt
do
exec {fds[n++]}< <(cut -d ' ' -f 1 "$file")
done

# fds now contain a list of fds like 12 14
# prepend "/dev/fd/" to all of them
parameters=( "${fds[@]/#//dev/fd/}" )

paste -d ' ' "${parameters[@]}"
)

{var}< file是 bash 的动态文件描述符分配语法。喜欢var=4; exec 4< file;但不必对 4 进行硬编码,而是让 bash 选择一个免费的文件描述符。 exec在当前 shell 中打开它。

* Linux、FreeBSD、OpenBSD 和 XNU/OSX。这不是 POSIX,但也不是 <(..)

关于bash - 将大量文件通过管道传输到标准输入,提取第一列,然后将它们合并到一个新文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36777098/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com