如何用 BASH 中的整个文件替换匹配项?

How to replace a match with an entire file in BASH?

我有这样一行:

输入文件 1

如何让 bash 读取该行并直接复制“file1.txt”的内容来代替该行?或者如果它看到: INPUT file2 在一行中,输入 `file2.txt" 等

我能做的最好的事情就是使用很多 tr 命令来将文件粘贴在一起,但这似乎是一个过于复杂的解决方案。

'sed'也是用字符串替换行,但是不知道怎么把一个文件的全部内容输入进去,替换成几百行。

awk 似乎非常简单。您可能希望优雅地处理错误 differently/more,但是:

$ cat file1
Line 1 of file 1
$ cat file2
Line 1 of file 2
$ cat input
This is some content
INPUT file1
This is more content
INPUT file2
This file does not exist
INPUT file3
$ awk '=="INPUT" {system("cat " ); next}1' input
This is some content
Line 1 of file 1
This is more content
Line 1 of file 2
This file does not exist
cat: file3: No such file or directory

如果您想在纯 Bash 中执行此操作,这里有一个示例:

#!/usr/bin/env bash

if (( $# < 1 )); then
    echo "Usage: ${0##*/} FILE..."
    exit 2
fi

for file; do
    readarray -t lines < "${file}"
    for line in "${lines[@]}"; do
        if [[ "${line}" == "INPUT "* ]]; then
            cat "${line#"INPUT "}"
            continue
        fi
        echo "${line}"
    done > "${file}"
done

保存到文件,然后 运行 像这样:./script.sh input.txt(其中 input.txt 是一个包含混合了 INPUT <file> 语句的文本的文件)。

Perl 单行代码,使用 CPAN 模块 Path::Tiny

perl -MPath::Tiny -pe 's/INPUT (\w+)/path(".txt")->slurp/e' input_file

使用 perl -i -M... 就地编辑文件。

这不是最有效的方法,但作为练习,我制作了一个名为 x 的要编辑的文件和几个名为 t1 & t2.[=16 的输入源=]

$: cat x
a
INPUT t2
b
INPUT t1
c
$: while read k f;do sed -ni "/$k $f/!p; /$k $f/r $f" x;done< <( grep INPUT x )
$: cat x
a

here's
 ==> t2

b

this
is
file ==> t1

c

是的,空白行在输入文件中。
不过,这将 sed 重复您的基础文件。
给出的 awk 解决方案更好,因为它只读了一次。

sed 类似于 awk 之前给定的解决方案:

$ cat f 
test1

INPUT f1

test2

INPUT f2

test3

$ cat f1
new string 1

$ cat f2
new string 2

$ sed 's/INPUT \(.*\)/cat /e' f
test1

new string 1

test2

new string 2

test3

Bash 变体

while read -r line; do
    [[ $line =~ INPUT.* ]] && { tmp=($BASH_REMATCH); cat ${tmp[1]}; } || echo $line
done < f