2017-05-03 38 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 
相關問題