2017-05-03 36 views
-1

文件1 - CSV的文件列表Shell或AWK帮助,我如何将一个文件中的特定文本替换为另一个文件?

Run_100000_data.csv 
Run_101001_data.csv 
Run_102002_data.csv 
... 
... 

(请注意,上面的列表中均能生长和文件常常是这种结构Run_6digit#_data.csv

文件2

LINEMAP [1] 
NAME = '&M#&' 
LINEMAP [2] 
NAME = '&M#&' 
LINEMAP [3] 
NAME = '&M#&' 

我会喜欢编写一个shell脚本,用文件2中的第一个实例&M#&替换文件1的第一行。这将重复第二行和第三行或文件中的行数。

输出:

LINEMAP [1] 
NAME = 'Run_100000' 
LINEMAP [2] 
NAME = 'Run_101001' 
LINEMAP [3] 
NAME = 'Run_102002' 

请注意,我没有使用全名从文件1,( '_data.csv' 不使用)。如果运行号码可以被替换,那也是可以接受的。我想留下这个开放式的结论来允许任何有创意的想法。任何帮助将非常感激!!

+0

在文件2中,是与串是线每隔两行就更换一次,或者可能在任何地方? –

+0

对延迟响应抱歉......要替换的字符串可能在任何地方。我试过了你的bash脚本,它的功能就像一个魅力!谢谢 – user7649922

回答

1

这里是一个bash脚本,做它:

#!/bin/bash 

macro='&M#&' 

while IFS= read -r line; do 
    if [[ $line == *${macro}* ]]; then 
     # Read replacement from fd 3/file1 
     read -r -u 3 rpl 
     # Compose output line with parameter substitutions 
     printf '%s%s%s\n' "${line%"$macro"*}" "${rpl%_data.csv}" "${line#*"$macro"}" 
    else 
     printf '%s\n' "$line" 
    fi 
# Read from file2, redirect fd 3 to read from file1, redirect output to outfile 
done < file2 3<file1> outfile 

这重定向file1文件描述符3,所以当我们在想我们可以从那里读循环。其余的是模式匹配和参数扩展。


如果file2有串线每月的第二个行被替换,我们可以使用paste和sed如下:

paste -d ' ' file2 <(paste -d '\n' /dev/null file1) | 
    sed 's/&M#&\(.*\) \([^[:blank:]]*\)_data\.csv$/\2\1/' 

说明:

  • paste -d '\n' /dev/null file1交错file1空行,导致

    file2在一起,空间分隔
    ​ 
    Run_100000_data.csv 
    
    Run_101001_data.csv 
    
    Run_102002_data.csv 
    
  • paste -d ' ' file2 <(paste -d '\n' /dev/null file1)膏:

    LINEMAP [1] 
    NAME = '&M#&' Run_100000_data.csv 
    LINEMAP [2] 
    NAME = '&M#&' Run_101001_data.csv 
    LINEMAP [3] 
    NAME = '&M#&' Run_102002_data.csv 
    
  • sed 's/&M#&\(.*\) \([^[:blank:]]*\)_data\.csv$/\2\1/'检查字符串被替换,抓住一切直到最后一个空就行了,并更换部分我们要和它重新排列,造成

    LINEMAP [1] 
    NAME = 'Run_100000' 
    LINEMAP [2] 
    NAME = 'Run_101001' 
    LINEMAP [3] 
    NAME = 'Run_102002' 
    
+0

bash脚本完美运行!非常感谢您花时间帮助我解决这个问题!我应该提到File 2包含其他行,所以在这种情况下,每隔一行替换一次字符串将不起作用。 – user7649922

1

这工作在我的测试与GNU AWK:

echo "$a" 
Run_100000_data.csv 
Run_101001_data.csv 
Run_102002_data.csv 

echo "$b" 
LINEMAP [1] 
NAME = '&M#&' 
LINEMAP [2] 
NAME = '&M#&' 
LINEMAP [3] 
NAME = '&M#&' 

awk -F"_" 'NR==FNR{f[FNR]=$1FS$2;next}FNR%2!=0{print $1;print "NAME = \x27"f[++c]"\x27"}' <(echo "$a") <(echo "$b") 
LINEMAP [1] 
NAME = 'Run_100000' 
LINEMAP [2] 
NAME = 'Run_101001' 
LINEMAP [3] 
NAME = 'Run_102002' 

在上述测试中,我用两个变量。你的情况,你可以使用

awk -F"_" 'NR==FNR{f[FNR]=$1FS$2;next}FNR%2!=0{print $1;print "NAME = \x27"f[++c]"\x27"}' file1 file2 
+0

原谅我,我不熟悉$ echo“$ a”。我使用bash,当我回显csvList.txt时,它不会告诉我内容是什么......它只是回显名称。 – user7649922

+0

@ user7649922好的,我会在我的回答中澄清它 –

+0

@ user7649922 OK-Clarified。 –

2
awk ' 
BEGIN { str = "&M#&" } 
NR==FNR { sub(/_[^_]+$/,""); a[NR] = $0; next } 
s = index($0,str) { $0 = substr($0,1,s-1) a[++c] substr($0,s+length(str)) } 
{ print } 
' file1 file2 
相关问题