Sed替换字符串,基于输入文件

时间:2015-06-09 08:11:16

标签: regex bash shell awk sed

想要查看是否有更好/更快的方法来执行此操作。

基本上,我有一个文件,我需要根据其中一个字段添加更多信息。 e.g。

要编辑的文件:

USER|ROLE
user1|role1
user1|role2
user2|role1
user2|role11

输入文件:

Role|Application
role1|applicationabc
role2|application_qwerty
role3|application_new_app_new
role4|qwerty_abc_123
role11|applicationabc123

最后,我想留下这样的东西:

USER|ROLE|Application
user1|role1|applicationabc
user1|role2|application_qwerty
user2|role11|applicationabc123
user2|role3|application_new_app_new

我的想法:

cat inputfile | while IFS='|' read src rep
do   
sed -i "s#\<$src\>#$src\|$rep#" /path/to/file/filename.csv
done

我所写的作品在某种程度上有效,但速度非常慢。此外,如果它在行中的任何位置找到匹配项,它将替换它。例如,对于user2和role11,脚本在匹配role11之前将匹配role1。

所以我的问题是:

  1. 有更快的方法吗?
  2. 有没有办法匹配确切的表达式/字符串?在我的输入文件中加上引号似乎无法正常工作。

3 个答案:

答案 0 :(得分:3)

使用join

join -i -t "|" -1 2 -2 1 <(sort -t '|' -k2b,2 file) <(sort -t '|' -k 1b,1 input)

从联接手册页:

  

重要提示:必须在连接字段上对FILE1和FILE2进行排序。

这就是为什么我们需要先对两个文件进行排序:第一个字段为file,第二个字段为input

然后join加入这些字段-1 2 -2 1上的两个文件。输出将是:

ROLE|USER|Application
role1|user1|applicationabc
role1|user2|applicationabc
role11|user2|applicationabc123
role2|user1|application_qwerty

答案 1 :(得分:2)

awk的小蛋糕:

$ cat file1
USER|ROLE
user1|role1
user1|role2
user2|role1
user2|role11

$ cat file2
ROLE|Application
role1|applicationabc
role2|application_qwerty
role3|application_new_app_new
role4|qwerty_abc_123
role11|applicationabc123

$ awk -F'\\|' 'NR==FNR{a[$1]=$2; next}; {print $0 "|" a[$2]}' file2 file1
USER|ROLE|Application
user1|role1|applicationabc
user1|role2|application_qwerty
user2|role1|applicationabc
user2|role11|applicationabc123

答案 2 :(得分:0)

请尝试以下方法:

awk 'FNR==NR{A[$1]=$2;next} $3 = $2 in A ? A[$2] : 0' FS='|' OFS='|' file2 file1

或:

 awk '
     # FNR==NR this is true only when awk reading first file

     FNR==NR{
                # Create array A where index = field1($1) and value = field2($2) 
                A[$1]=$2

                # stop processing and go to next line
                next
            }

   # Here we read 2nd file that is file1 in your case
   # var in Array returns either 1=true or 0=false
   # if array A has index field2 ($2) then s will be 1 otherwise 0 
   # whenever s is 1 that is nothing but true state, we create new field
   # $3 and its value will be array element corresponds to array index field2

   s=$2 in A{
               $3=A[$2] 
            }s

  # An awk program is a series of condition-action pairs, 
  # conditions  being outside of curly braces and actions being enclosed in them. 
  # A condition is considered false if it evaluates to zero or the empty string,
  # anything else is true (uninitialized variables are zero or empty string, 
  # depending on context, so they are false). 
  # Either a condition or an action can be implied; 
  # braces without a condition are considered to have a true condition and 
  # are always executed if they are hit,
  # and any condition without an action will print the line 
  # if and only if the condition is met.

  # So finally }s at the end of script
  # it executes the default action for every line, 
  # printing the line whenever s is 1 that is true 
  # which may have been modified by the previous action in braces

  # FS  = Input Field Separator
  # OFS = Output Field Separator

    ' FS='|' OFS='|' file2 file1

<强>解释

UPDATE table SET columnB = columnA