替换存储在变量中的单词

时间:2014-10-02 12:10:54

标签: bash shell unix sed

#!/bin/bash
IFS=''
replace="XXX"
for line in `cat test.csv`;do
name=`echo $line|cut -d"|" -f1`
      date=`echo $line|cut -d"|" -f3`
      echo $name
      echo $date
      sed -n "s/$name/XXX/gpw" output' test.csv
done

我需要将$name的值替换为XXX,但它不起作用。

CSV文件包含:

38880|update|20121227|customerXXXX|CXXX|Credit|Comp any|channel:XXX|XXX|XXX|0|Active|N|N|2012-12-31 17:37:46|Y|2012-12-31 17:37:46

错误是:

sed: -e expression #1, char 8: unterminated `s' command

3 个答案:

答案 0 :(得分:2)

我认为你做的事太多了,只是为了改变第一栏。

这应该是:

awk -v subs="XXX" 'BEGIN{FS=OFS="|"} {$1=subs}1' file

对于您的给定输入,它返回:

XXX|update|20121227|customerXXXX|CXXX|Credit|Comp any|channel:XXX|XXX|XXX|0|Active|N|N|2012-12-31 17:37:46|Y|2012-12-31 17:37:46

要更新文件,请使用:

awk -v subs="XXX" 'BEGIN{FS=OFS="|"} {$1=subs}1' file > new_file && mv new_file file

如果您需要使用bash,可以像这样使用IFSread

while IFS="|" read -r name _ date _
do
   echo $name
   echo $date
   sed -i.bak "s/$name/XXX/g" another_file #do the replacement
done < file

注意$name获取第一个字段的值,$date获取第三个字段的值,基于|作为分隔符。

答案 1 :(得分:1)

首先,您可以使用while代替for来大大简化事情。您也不需要sed。 Bash和其他shell有一些相当广泛的string manipulation abilities。因此,您的脚本的工作版本可能是:

$ while IFS='|' read -r name rest; do 
    printf "XXX|%s\n" "$rest"
 done < test.csv > new.csv
XXX|update|20121227|customerXXXX|CXXX|Credit|Comp any|channel:XXX|XXX|XXX|0|Active|N|N|2012-12-31 17:37:46|Y|2012-12-31 17:37:46

这会将新行写入new.csv文件。如果您还想将$name$date的值回显到终端,但只保存更改的文件,请改用:

$ > new.csv; while IFS='|' read -r name f2 date rest; do 
    printf "%s\n%s\n" "$date" "$name" 
    printf "XXX|%s|%s|%s\n" "$f2" "$date" "$rest" >> new.csv
 done < test.csv 

你似乎也希望做更多的操作。如果是这样,您可以将每个字段读入变量:

while IFS='|' read -r f{1..10}; do ... ;done; done < test.csv 

这些字段将以$f1$f15的形式提供。或者,您可以使用数组:

$ while IFS='|' read -r -a fields; do 
    for((i=0; i<${#fields[@]}; i++)); do 
        echo "Field $i : ${fields[$i]}" 
    done 
done < test.csv 
Field 0 : 38880
Field 1 : update
Field 2 : 20121227
Field 3 : customerXXXX
Field 4 : CXXX
Field 5 : Credit
Field 6 : Comp any
Field 7 : channel:XXX
Field 8 : XXX
Field 9 : XXX
Field 10 : 0
Field 11 : Active
Field 12 : N
Field 13 : N
Field 14 : 2012-12-31 17:37:46
Field 15 : Y
Field 16 : 2012-12-31 17:37:46

答案 2 :(得分:0)

sed 'h;s/^\([^|]*\)|[^|]*|\([^|]*\)|.*/\1\
\2/p
g
:a
s/^\([^|]*\)\(|.*\)\1/\1\2XXX/
t a
s/^\([^|]*\)|/XXX|/' test.csv

试试这个。

  1. 提取并打印名称+日期
  2. 以递归方式替换行中的名称
  3. 替换首次出现的名称