AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1288403
Accepted
Insideup
Insideup
Asked: 2020-10-31 12:38:06 +0800 CST2020-10-31 12:38:06 +0800 CST 2020-10-31 12:38:06 +0800 CST

如何在匹配模式的行上替换不同数量的字符串

  • 772

文件 1

<filename1.txt> stringA string1
<filename2.txt> stringA string2
<filename2.txt> stringB string3

文件2

<filename1.txt>      words and symbols < $ stringA words and symbols 9 
<filename2.txt>      more words and symbols % @ stringA words and symbols stringB

File2 已转换

<filename1.txt>      words and symbols < $ string1 words and symbols 9
<filename2.txt>      more words and symbols % @ string2 words and symbols string3

我的方法是遍历 File1 的行来设置变量。所以对于第 1 行,vars 设置为:

filenamevar = <filename1.txt>
string_old_var = stringA 
string_new_var = string1 

然后 grep 匹配 filenamevar 和 string_old_var 的行作为 sed 的输入。这就是我需要帮助的地方(除非您认为有更好的方法)。

到目前为止最接近的是

grep -e "$filenamevar.*$string_old_var" File2.txt | sed s/$string_old_var/$string_new_var/ >> File2Transformed.txt

除了第二行输出两次之外,它的工作原理:

<filename1.txt>      words and symbols < $ string1 words and symbols 9 
<filename2.txt>      more words and symbols % @ string2 words and symbols stringB
<filename2.txt>      more words and symbols % @ stringA words and symbols string3

我也试过

grep -e "$filenamevar.*$string_old_var" File2 | sed s/$string_old_var/$string_new_var/

和

sed -i s/$string_old_var/$string_new_var/ $(grep -e "$filenamevar.*$string_old_var" File2)

但两者都不会产生预期的结果。

这是我正在使用的循环

Numlines=$(grep "" -c File1.txt) 
for (( line=1; line<=$Numlines; line++ )) ; do 
 filenamevar=$(awk -v line=$line 'NR == line {print $1}' File1.txt) 
 string_old_var=$(awk -v line=$line 'NR == line {print $2}' File1.txt)
 string_new_var=$(awk -v line=$line 'NR == line {print $3}' File1.txt)
 # insert proper sed grep code to test here
done
scripts command-line bash sed grep
  • 1 1 个回答
  • 85 Views

1 个回答

  • Voted
  1. Best Answer
    steeldriver
    2020-10-31T14:55:48+08:002020-10-31T14:55:48+08:00

    如果您决定为此使用 shell 循环,您可以执行类似的操作

    while read -r fname patt repl; do 
      sed -i.bak "/$fname/s/^$patt/$repl/" File2
    done < File1
    

    但请注意,如果您的任何字符串包含正则表达式特殊字符序列,它可能会以意想不到的方式中断。另一种选择(对特殊字符具有相同的警告)将类似于

    awk '{printf "/^%s/s/%s/%s/\n",$1,$2,$3}' File1 | sed -f- File2
    

    它用于awk将 File1 格式化为一系列命令,然后通过管道将其sed -f用于修改 File2。

    使用支持 2D 数组的 GNU awk (aka gawk),您可以这样做:

    $ gawk '
        NR==FNR {a[$1][$2] = $3; next} 
        $1 in a {for(i=2;i<=NF;i++) $i = $i in a[$1] ? a[$1][$i] : $i} 
        1
      ' File1 File2
    <filename1.txt> words and symbols < $ string1 words and symbols 9
    <filename2.txt> more words and symbols % @ string2 words and symbols string3
    

    或者如果您需要保持对齐,请使用以下index功能substr:

    $ gawk '
        NR==FNR {a[$1][$2] = $3; next}
        $1 in a {
          for(s in a[$1]) {
            mstart = index($0,s);
            if(mstart > 0) $0 = substr($0,1,mstart-1) a[$1][s] substr($0,mstart+length(s))}
        }
        1
      ' File1 File2
    <filename1.txt>      words and symbols < $ string1 words and symbols 9
    <filename2.txt>      more words and symbols % @ string2 words and symbols string3
    

    vanilla awk 中的类似事情,用 FS 分隔的字符串伪造 2D 数组:

    mawk '
      NR==FNR {a[$1 FS $2] = $3; next}
      {
        for(k in a) {
          split(k,b);
          if($1 == b[1]) {
            mstart = index($0,b[2]);
            if(mstart > 0) $0 = substr($0,1,mstart-1) a[k] substr($0,mstart+length(b[2]));
          }
        }
      }
      1 
    ' File1 File2
    
    • 1

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve