簡體   English   中英

sed替換字符串,基於輸入文件

[英]Sed replace string, based on input file

想看看是否有更好/更快的方法來做到這一點。

基本上,我有一個文件,我需要根據其一個字段向其中添加更多信息。 例如

修改文件:

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. 有沒有辦法與確切的表達式/字符串匹配? 在我的輸入文件中加引號似乎不起作用。

隨着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

同一塊蛋糕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

請嘗試以下操作:

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

要么:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM