2017-05-03 14 views
-1

ファイル1 - CSVファイルのリストシェルまたは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#&' 

私は考えファイル1の1行目をファイル2にある&M#&の最初のインスタンスに置き換えるシェルスクリプトを書きます。これは2行目と3行目またはファイル内の行数だけ繰り返されます。

出力:

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

私は( '_data.csv' が使用されていない)、ファイル1から完全な名前を使用していないのでご注意ください。ランナンバーを代用できる場合は、それも許容されます。私はこれをオープンにして、創造的なアイデアを可能にしておきたいと思います。どんな助けでも大歓迎です!!

+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 

これは私たちが中にしたいときに、我々はそこから読み取ることができます記述子3を提出しfile1をリダイレクトループ。残りの部分はパターンマッチングとパラメータ展開です。

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

説明:

  • paste -d '\n' /dev/null file1インターリーブをfile2が2行ごとに交換する文字列と行を持っている


    場合は、次のように、我々はpasteを使用し、sedのできますfile1が空白行の場合、

    一緒にfile2で、スペースが区切らの
    ​ 
    Run_100000_data.csv 
    
    Run_101001_data.csv 
    
    Run_102002_data.csv 
    
  • paste -d ' ' file2 <(paste -d '\n' /dev/null file1)ペースト:stringの

    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/'チェック交換するには、行の最後の空白や交換の一部までのすべてのものをキャプチャし、我々欲しいとファイル2で

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

bashスクリプトは完璧に機能しました!私にこれを手伝ってくれてありがとう!ファイル2には他の行が含まれているので、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' 

私は2つの変数を使用します。あなたのケースでは、あなたはここで

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 OK、私は私の答えでそれを明確にします –

+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 
関連する問題