将变量传递给 sed 命令

将变量传递给 sed 命令

我们有一个包含 6 列的文件:

FILEDESCRIPTOR . DESCR00001     FILEDESCRIPTOR  .  DESCRIPTIVENAME
FILEDESCRIPTOR . LSTUPDNAM      FILEDESCRIPTOR  .  LASTUPDATENAME
FILEDESCRIPTOR . LOCAT00001     FILEDESCRIPTOR  .  LOCATION_ID
FILEDESCRIPTOR . RETAILPRC      FILEDESCRIPTOR  .  RETAILPRICE
FILEDESCRIPTOR . LSTUPDTIME     FILEDESCRIPTOR  .  UPDTIMESTAMP
INDUSTRYDIVISION . DESCR00001   INDUSTRYDIVISION  .  DESCRIPTION
INDUSTRYDIVISION . DIVIS00001   INDUSTRYDIVISION  .  DIVISIONCODE
INDUSTRYGROUP . DESCR00001      INDUSTRYGROUP  .  DESCRIPTION
INDUSTRYGROUP . DIVIS00001      INDUSTRYGROUP  .  DIVISION_ID

我需要做的就是处理由单个空格分隔的前 3 列,并将其作为单个列存储在变量中,然后将由单个空格分隔的接下来的三列存储到另一个变量中。然后,使用sed第二个变量替换第一个变量。

我尝试了下面的脚本但抛出了错误:

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]];
do
        column2="$(echo -e "$line \n" | awk '{print $4, $5, $6}')"
        #column3="$(echo -e "$line \n" | awk '{print $3}')"
        column1="$(echo -e "$line \n" | awk '{print $1, $2, $3}' )"
        #echo " $column1"
        #echo " $column2"
                 sed  "s/${column1}/${column2}/g" IMS_Procedures.txt
done < file

该脚本不起作用。我得到的错误是:

sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 20: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 22: unterminated `s' command
sed: -e expression #1, char 22: unterminated `s' command
sed: -e expression #1, char 22: unterminated `s' command
sed: -e expression #1, char 23: unterminated `s' command
sed: -e expression #1, char 30: unterminated `s' command

可以做什么?

答案1

不需要while read...
您可以简单地处理您的输入文件:

sed 's|[[:blank:]]\{1,\}|/|3;s|.*|s/&/g|' infile

并将其变成sed脚本:

s/FILEDESCRIPTOR . DESCR00001/FILEDESCRIPTOR . DESCRIPTIVENAME/g
s/FILEDESCRIPTOR . LSTUPDNAM/FILEDESCRIPTOR . LASTUPDATENAME/g
s/FILEDESCRIPTOR . LOCAT00001/FILEDESCRIPTOR . LOCATION_ID/g
s/FILEDESCRIPTOR . RETAILPRC/FILEDESCRIPTOR . RETAILPRICE/g
s/FILEDESCRIPTOR . LSTUPDTIME/FILEDESCRIPTOR . UPDTIMESTAMP/g
s/INDUSTRYDIVISION . DESCR00001/INDUSTRYDIVISION . DESCRIPTION/g
s/INDUSTRYDIVISION . DIVIS00001/INDUSTRYDIVISION . DIVISIONCODE/g
s/INDUSTRYGROUP . DESCR00001/INDUSTRYGROUP . DESCRIPTION/g
s/INDUSTRYGROUP . DIVIS00001/INDUSTRYGROUP . DIVISION_ID/g

并将其传递给第二个sed -f-来处理您的 IMS_ Procedures.txt

sed 's|[[:blank:]]\{1,\}|/|3;s|.*|s/&/g|' infile | sed -f- IMS_Procedures.txt

我不太明白“这是一个文件,这个命令用单个空格打印它”是什么意思,所以如果您中的字段infile由多个空格分隔,那么您可以tr先使用:

tr -s '[[:blank:]]' ' ' <infile | sed 's| |/|3;s|.*|s/&/g|' | sed -f- IMS_Procedures.txt

答案2

在您的$column1and$column2变量中,末尾有一个换行符,sed命令如下所示:

sed  "s/FILEDESCRIPTOR . DESCR00001
  /FILEDESCRIPTOR . DESCRIPTIVENAME
  /g" IMS_Procedures.txt

sed将此识别为未终止的 s 命令。


使用这个代替:

while read -r a b c d e f; do
  sed -i "s/$a $b $c/$d $e $f/g" IMS_Procedures.txt
done <file
  • read将 6 个字段存储在变量$a$f
    • 然后sed用文件中的后 3 个字段替换作为空格分隔字符串的前 3 个字段IMS_Procedures.txt-i激活就地编辑,将更改写入文件,而不是打印到屏幕上。

请注意,.insed将匹配任何字符,而不仅仅是点。必须\.在输入中转义file

答案3

我会尝试显而易见的:

awk '{printf "s/%s%s%s/%s%s%s/\n",$1,$2,$3,$4,$5,$6} ' file |
sed -i -f - IMS_Procedures.txt

其中 sed 文件是由 awk 生成的。

您可以使用调整空间

awk '{printf "s/%s %s %s/%s %s %s/\n",$1,$2,$3,$4,$5,$6}

相关内容