Unix代码想要复制模板文件并替换复制文件中模板文件中的字符串

时间:2012-03-28 19:26:56

标签: bash sed

我有2个文件:

File_1.txt:

John
Mary
Harry
Bill

File_2.txt:

My name is ID, and I am on line NR of file 1.

我想创建四个看起来像这样的文件:

Output_file_1.txt:

My name is John, and I am on line 1 of file 1.

Output_file_2.txt:

My name is Mary, and I am on line 2 of file 1.

Output_file_3.txt:

My name is Harry, and I am on line 3 of file 1.

Output_file_4.txt:

My name is Bill, and I am on line 4 of file 1.

通常我会使用以下sed命令来执行此操作:

for q in John Mary Harry Bill
do  
sed 's/ID/'${q}'/g' File_2.txt > Output_file.txt
done

但是这只会替换名称的ID,而不包括File_1.txt的行号。不幸的是,我的bash技能没有比这更进一步......对于包含文件1和2的命令的任何提示或建议?我确实需要包含文件1,因为实际上文件比这个例子大得多,但我想如果我知道如何用这个希望更简单的例子来解决其余的代码......很多提前谢谢!

6 个答案:

答案 0 :(得分:9)

怎么样:

n=1
while read q
  do  
  sed -e 's/ID/'${q}'/g' -e "s/NR/$n/" File_2.txt > Output_file_${n}.txt
  ((n++))
done < File_1.txt

请参阅Advanced Bash Scripting Guide on redirecting input to code blocks,或许the section on double parentheses进一步阅读。

答案 1 :(得分:3)

awk怎么样呢?

[ghoti@pc ~]$ cat file1
John
Mary
[ghoti@pc ~]$ cat file2
Harry
Bill
[ghoti@pc ~]$ cat merge.txt 
My name is %s, and I am on the line %s of file '%s'.
[ghoti@pc ~]$ cat doit.awk 
#!/usr/bin/awk -f

BEGIN {
  while (getline line < "merge.txt") {
    fmt = fmt line "\n";
  }
}

{
  file="Output_File_" NR ".txt";
  printf(fmt, $1, FNR, FILENAME) > file;
}

[ghoti@pc ~]$ ./doit.awk file1 file2
[ghoti@pc ~]$ grep . Output_File*txt
Output_File_1.txt:My name is John, and I am on the line 1 of file 'file1'.
Output_File_2.txt:My name is Mary, and I am on the line 2 of file 'file1'.
Output_File_3.txt:My name is Harry, and I am on the line 1 of file 'file2'.
Output_File_4.txt:My name is Bill, and I am on the line 2 of file 'file2'.
[ghoti@pc ~]$ 

如果您真的希望对文件名进行编号,我们也可以这样做。

这里发生了什么?

awk脚本BEGIN通过读取merge.txt文件并逐行将其附加到变量“fmt”(由换行符分隔)。这使fmt成为printf兼容格式字符串。

然后,对于输入文件中的每一行(在命令行中指定),选择一个输出文件(NR是跨越所有文件的当前记录计数)。 printf()函数用其中一个选项替换fmt变量中的每个%s。输出被重定向到适当的文件。

grep只会显示所有文件的内容及其文件名。

答案 2 :(得分:1)

这可能对您有用:

sed '=' File_1.txt |
sed '1{x;s/^/'"$(<File_2.txt)"'/;x};N;s/\n/ /;G;s/^\(\S*\) \(\S*\)\n\(.*\)ID\(.*\)NR\(.*\)/echo "\3\2\4\1\5" >Output_file_\1.txt/' |
bash

答案 3 :(得分:1)

TXR:

$ txr merge.txr
My name is John, and I am on the line 1 of file1.
My name is Mary, and I am on the line 2 of file1.
My name is Harry, and I am on the line 3 of file1.
My name is Bill, and I am on the line 4 of file1.

merge.txr:

@(bind count @(range 1))
@(load "file2.txt")
@(next "file1.txt")
@(collect)
@name
@(template name @(pop count) "file1")
@(end)

file2.txt:

@(define template (ID NR FILE))
@(output)
My name is @ID, and I am on the line @NR of @FILE.
@(end)
@(end)

答案 4 :(得分:1)

  • 将名称读入数组。
  • 获取数组长度
  • 遍历数组

测试准备:

echo "John
Mary
Harry
Bill
" > names 

姓名和号码:

name=($(<names))
max=$(($(echo ${#name[*]})-1))
for i in $(seq 0 $max) ; do echo $i":"${name[i]}; done

使用模板:

for i in $(seq 0 $max) ; do echo "My name is ID, and I am on the line NR of file 1." | sed "s/ID/${name[i]}/g;s/NR/$((i+1))/g";   done 
My name is John, and I am on the line 1 of file 1.
My name is Mary, and I am on the line 2 of file 1.
My name is Harry, and I am on the line 3 of file 1.
My name is Bill, and I am on the line 4 of file 1.

答案 5 :(得分:1)

您的脚本需要稍加修改。请注意。

pearl.306> cat temp.sh
#!/bin/ksh

count=1
cat file1|while read line
do
sed -e "s/ID/${line}/g" -e "s/NR/${count}/g" File_2.txt > Output_file_${count}.txt
count=$(($count+1))
done
pearl.307>

pearl.303> temp.sh
pearl.304> ls -l Out*
-rw-rw-r--   1 nobody   nobody        59 Mar 29 18:54 Output_file_1.txt
-rw-rw-r--   1 nobody   nobody        58 Mar 29 18:54 Output_file_2.txt
-rw-rw-r--   1 nobody   nobody        58 Mar 29 18:54 Output_file_3.txt
-rw-rw-r--   1 nobody   nobody        58 Mar 29 18:54 Output_file_4.txt
-rw-rw-r--   1 nobody   nobody        58 Mar 29 18:54 Output_file_5.txt
pearl.305> cat Out*
My name is linenumber11, and I am on the line 1 of file 1.
My name is linenumber2, and I am on the line 2 of file 1.
My name is linenumber1, and I am on the line 3 of file 1.
My name is linenumber4, and I am on the line 4 of file 1.
My name is linenumber6, and I am on the line 5 of file 1.
pearl306>