如何在word中添加字符并在linux中使用sed命令替换它

Posted

技术标签:

【中文标题】如何在word中添加字符并在linux中使用sed命令替换它【英文标题】:How to add characters in word and replace it using sed command in linux 【发布时间】:2021-01-16 23:21:11 【问题描述】:

我有一个要求。

我有一个名为 a.txt 的文本文件,其中包含单词列表 -

GOOGLE
FACEBBOK

现在我有了另一个名为 b.txt 的文件,其内容为

Company name is google.
Company name is facebook.

像这样的n行有不同的单词。

那我在写脚本文件-

    FILENAME="a.txt"

SCHEMA=$(cat $FILENAME)

for L in $SCHEMA
do
    echo "$L,,"

sed -i -E "s/.+/\L&_/" b.txt
done

所以在运行脚本后,我期待的 b.txt 文件的输出文件是

 Company name is google_
 Company name is facebook_

但是运行该脚本后我得到的输出是 -

Company name is google.__
Company name is facebook.__

正如我在 sed 命令中提到的那样,此输出将保存在 b.txt 文件中

注意 - 在 a.txt 我有我想要替换的单词列表,在 b.txt 文件中我有我在其中的行的段落我有 google.facebook. 等词。

所以这就是为什么我无法直接发出 sed 命令进行替换。

希望你能理解我的要求。

提前致谢!

【问题讨论】:

切线,don't use upper case for your private variables. 【参考方案1】:

您可以使用以下 GNU sed 解决方案:

FILENAME="a.txt"
while IFS= read -r L; do
  sed -i "s/\($L\)\./\1_/gI" b.txt
done < $FILENAME

或者,与单行一样没有循环(如anubhava's answer 中使用的):

sed -i -f <(printf 's/\\(%s\\)\\./\\1_/gI\n' $(<"$FILENAME")) b.txt

有了脚本,你

while IFS= read -r L; do - 逐行读取文件,每一行都分配给L sed -i "s/\($L\)\./\1_/gI" b.txt - 用b.txt 替换b.txt 中所有出现的L(在捕获\(...\) 括号的帮助下被捕获到第1 组)后跟.(由于I 标志不区分大小写)与第 1 组中捕获的值相同,并附加了_-f 允许将命令列表传递给 sed printf 's/\\(%s\\)\\./\\1_/gI\n' $(&lt;"$FILENAME") 创建一个 sed 命令列表,在这种情况下,它看起来像
s/\(GOOGLE\)\./\1_/gI
s/\(FACEBOOK\)\./\1_/gI

【讨论】:

感谢@Wiktor Stribiżew 的回复。实际上,在应用您的脚本后,我得到的输出为 - google.__ 和 facebook.__ 是双“_”,它正在添加而不是消除“。”还。你能帮我解决这个问题吗?实际上在 a.txt 我有我想在 b.txt 文件中更改的单词列表。所以为每个单词申请循环。 @saurabh704 如果您的输入中没有.,为什么要消除.?还是您分享了错误的输入?您使用的是sed -i -E "s/.+/\L&amp;_/" 还是sed -i "s/.*/\L&amp;_/"?如果您使用后者,请尝试sed -i "s/..*/\L&amp;_/" 感谢@Wiktor Stribiżew 抽出宝贵时间。我已经编辑了问题,请看看您是否能够理解我的要求。 @saurabh704 查看我的新答案。是的,修改后问题就清晰多了。【参考方案2】:

以下是在进程替换中使用 gnu-sedprintf 在单个 shell 命令中执行此操作的方法:

sed -i -E -f <(printf 's/\\b(%s)\\./\\1_/I\n' $(<a.txt)) b.txt

cat b.txt
Company name is google_
Company name is facebook_

如果输入文件很大,这将比在循环中运行 sedawk 效率更高。

printf 命令正在创建一个 sed 命令脚本,如下所示:
s/\b(GOOGLE)\./\1_/I
s/\b(FACEBOOK)\./\1_/I
sed -f 运行动态生成的脚本

【讨论】:

非常感谢@anubhava。不使用循环也对我有用 @saurabh704,嘿 Saurabh,如果对您有帮助,您能否也检查一下我的解决方案?【参考方案3】:

使用单个awk 读取 2 个 Input_files,请尝试关注。

awk '
FNR==NR
  a[tolower($0)]
  next

($(NF-1) in a)
  sub(/\.$/,"")
  print $0"_"

' a.txt FS="[ .]" b.txt

说明:为上述解决方案添加详细说明。

awk '                        ##Starting awk program from here.
FNR==NR                     ##Checking condition FNR==NR which will be TRUE when a.txt is being read.
  a[tolower($0)]             ##Creating array a with index of current line in lower case from a.txt here.
  next                       ##next will skip all further statements from here.

($(NF-1) in a)              ##Checking condition if 2nd last field is present in array a then do following.
  sub(/\.$/,"")              ##Substituting last DOT with NULL here.
  print $0"_"                ##Printing current line with _ here.

' a.txt FS="[ .]" b.txt      ##Mentioning a.txt and setting field separator as space and . for b.txt here.


第二个解决方案:在此处添加 1 个带有 awk 的解决方案。

awk '
FNR==NR
  a[tolower($0)]
  next


  sub(/\.$/,"")

($NF in a)
  print $0"_"

' a.txt b.txt

【讨论】:

【参考方案4】:

这可能对你有用(GNU sed):

sed 's#.*#s/(&)./\\1_/Ig#' a.txt | sed -i -Ef - b.txt

注意由于替换命令上的I 标志,匹配不区分大小写,但是替换来自原始文件,即如果原始字符串为google,则匹配对GOOGLE 不区分大小写并由google_ 替换。

【讨论】:

以上是关于如何在word中添加字符并在linux中使用sed命令替换它的主要内容,如果未能解决你的问题,请参考以下文章

使用 sed 从字符串中删除单斜杠而不是双斜杠

linux中sed命令如何运用‘\ ’ 反斜杠

使用 sed 更改路径并在复制功能中使用结果?

linux sed 如何替换字符串中的反斜杠\

如何在Unix下使用sed命令

读取带有特殊字符的字符串并在`tr`和`sed`中使用它[关闭]