【问题标题】:How to write to a file in linux upon a condition [duplicate]如何根据条件写入linux中的文件[重复]
【发布时间】:2020-11-08 05:01:13
【问题描述】:

这可能很简单,但我需要这样做:

我有一个文件名a.sh,它包含以下几行

# firstname banuka
firstcolor green
lastname jananath
# age 25

我想将firstname banuka 写入这个文件,所以它看起来像

echo "firstname banuka" > a.sh

但是,在写 firstname banuka 之前,我想检查文件是否已经具有该值(或行)

正如您在a.sh 的文件内容中看到的那样,我们要编写的部分(firstname banuka)可能已经存在但带有注释。

So if it has a comment,
   1. I want to un-comment it (remove `#` in front of `firstname banuka`)
If no comment and no line which says `firstname banuka`,
   2. Add the line `firstname banuka`
If no comment and line is already there,
   3. skip (don't write `firstname banuka` part to file)

有人可以帮帮我吗?

【问题讨论】:

  • 我可以像 echo "firstname banuka" > a.sh 这样写入文件,但这就是我能实现的全部
  • > 将清除您可能指的文件>>

标签: bash shell


【解决方案1】:
string="firstname banuka"
file=./a.sh

grep -qwi "^[^[:alnum:]]*$string$" "$file" && \
sed -i "s,\(^[^[:alnum:]]*\)\($string$\),\2,i" "$file" || \
printf "\n%b\n" "$string" >> "$file"

【讨论】:

  • CRLF 行尾除外(因为$ 只捕获\n 换行)
【解决方案2】:

您需要使用一种可以扫描模式、具有变量并具有条件结构的编程语言。 awk 就是这样一种语言:

awk -v text="firstname banuka" '
    $0 ~ text {
        found = 1          # remember that we have seen it
        sub(/^ *# */, "")  # remove the comment, if there is one
    }
    {print}
    END {if (!found) {print text}}
' file

这不会编辑文件,只是打印出来。使用 GNU awk,如果您想就地编辑文件:

gawk -i inplace -v text="..." '...' file

用普通的 bash 你会写

found=false
while IFS= read -r line; do
    if [[ "$line" == *"firstname banuka"* ]]; then
        found=true
        if [[ "$line" =~ ^[[:blank:]]*[#][[:blank:]]*(.+) ]]; then
            line="${BASH_REMATCH[1]}"
        fi
    fi
    echo "$line"
done < file
$found || echo "firstname banuka"

【讨论】:

  • 抱歉,这不会写入文件。我添加了$found || echo "firstname banuka" &gt;&gt; test.txt,但如果文件中已经注释了文本,它不会取消注释。
【解决方案3】:

替代 Bash 实现

#!/usr/bin/env bash

found=false
while IFS= read -r line; do
    if [[ "$line" =~ ^([[:blank:]]*[#][[:blank:]]*)?(firstname banuka) ]]; then
        echo "${BASH_REMATCH[2]}"
        found=true
    else
      echo "$line"
    fi
done < a.txt
$found || echo "firstname banuka"

【讨论】:

  • 当有评论firstname banuka时这不起作用,如果有评论我想取消评论它
  • @user13456401 在echo "${BASH_REMATCH[2]}" 之前插入一个typeset -p BASH_REMATCH;并检查输出。我怀疑您没有使用 Bash 而是使用 zsh 。这仅适用于 Bash。
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 2015-01-29
  • 2021-04-16
  • 1970-01-01
  • 2018-03-03
  • 2020-02-22
  • 2016-04-06
  • 1970-01-01
相关资源
最近更新 更多