使用 Bash 读取文件中的行并避免使用 # 行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8195950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:12:35  来源:igfitidea点击:

Reading lines in a file and avoiding lines with # with Bash

bashloopscomments

提问by nixnotwin

I tried this:

我试过这个:

file="myfile"
while read -r line
do
    [[ $line = \#* ]] && continue
    "address=$line7.0.0.1"
done < "$file"

This code doesn't avoid the lines that begin with comments. Even if I don't have any comments, dnsmasqtells that there are errors.

此代码不会避免以注释开头的行。即使我没有任何评论,也dnsmasq告诉我有错误。

Its going to be a dnsmasqconf file, and it will read and insert domain names like so: address=\mydomain.com\127.0.0.1.

它将是一个dnsmasqconf 文件,它将像这样读取和插入域名:address=\mydomain.com\127.0.0.1.



EDIT:1

编辑:1

Input file:

输入文件:

domain1.com
domain2.com
domain3.com
#domain4.com
domain5.com

Output should be:

输出应该是:

address=/domain1.com/127.0.0.1
address=/domain2.com/127.0.0.1
address=/domain3.com/127.0.0.1
address=/domain5.com/127.0.0.1

I will drop the script in /etc/dnsmasq.d/directory so that dnsmaq.confcan process it when dnsmasqis started.

我会将脚本放在/etc/dnsmasq.d/目录中,以便dnsmaq.confdnsmasq启动时可以处理它。

采纳答案by ДМИТРИЙ МАЛИКОВ

It's safer to use [[ "$line" = "\#*" ]]

使用起来更安全 [[ "$line" = "\#*" ]]

Btw, address="\\${line}\\127.0.0.1"

顺便提一句, address="\\${line}\\127.0.0.1"

UPD:

更新

If I've understand you right you need to change every uncommented domains to address=\domain\127.0.0.1. It could be done fast and easy with sed, there is no need in bash-program.

如果我理解正确,您需要将每个未注释的域更改为address=\domain\127.0.0.1. 使用 可以快速轻松地完成sed,不需要 bash 程序。

$> cat ./text
domain1.com
domain2.com
domain3.com
#domain4.com
domain5.com

$> sed -r -e 's/(^[^#]*$)/address=\/\/127.0.0.1/g' ./text2
address=/domain1.com/127.0.0.1
address=/domain2.com/127.0.0.1
address=/domain3.com/127.0.0.1
#domain4.com
address=/domain5.com/127.0.0.1

If you need to remove commented lines, sed can do it too with /matched_line/d

如果您需要删除注释行, sed 也可以使用 /matched_line/d

$> sed -r -e 's/(^[^#]*$)/address=\/\/127.0.0.1/g; /^#.*$/d' ./text2 
address=/domain1.com/127.0.0.1
address=/domain2.com/127.0.0.1
address=/domain3.com/127.0.0.1
address=/domain5.com/127.0.0.1

UPD2: if you want to do all that stuff inside the bash script, here is your code modification:

UPD2:如果你想在 bash 脚本中做所有这些事情,这里是你的代码修改:

file="./text2"
while read -r line; do
    [[ "$line" =~ ^#.*$ ]] && continue
    echo "address=/${line}/127.0.0.1"
done < "$file"

And it's output:

它的输出:

address=/domain1.com/127.0.0.1
address=/domain2.com/127.0.0.1
address=/domain3.com/127.0.0.1
address=/domain5.com/127.0.0.1

回答by Keith Thompson

To skip lines startingwith #:

要跳过线开始#

grep -v '^#' myfile | while read -r file ; do
    ...
done

Modify the grepcommand as needed to, for example, skip lines starting with whitespace and a #character.

grep根据需要修改命令,例如,跳过以空格和#字符开头的行。

回答by briceburg

Comment lines can and often do begin with whitespace. Here's a bash native regex solution that handles any preceeding whitespace;

注释行可以并且经常以空格开头。这是一个 bash 原生正则表达式解决方案,可以处理任何前面的空格;

while read line; do
  [[ "$line" =~ ^[[:space:]]*# ]] && continue
  ...work with valid line...
done

回答by Pipo

Only one working for me was:

只有一个对我来说有效的是:

while IFS=$'\n' read line
do  
    if [[ "$line" =~ \#.* ]];then
        logDebug "comment line:$line"
    else
        logDebug "normal line:$line"
    fi
done < myFile

回答by JoJo Brandon Coffman

[ "${line:0:1}" = "#" ] && continue

This takes the string, gets the substring at offset 0, length 1:

这需要字符串,在偏移量 0处获取子字符串,长度为 1

"${line:0:1}"

and checks if it is equal to #

并检查它是否等于 #

= "#"

and continues looping if so

并继续循环如果是这样

&& continue

http://www.tldp.org/LDP/abs/html/string-manipulation.html

http://www.tldp.org/LDP/abs/html/string-manipulation.html

回答by Claes Wikner

You can filter with awk:

你可以过滤awk

awk '!/^#/{print"address=/"
file="myfile"

sed -i".backup" 's/^#.*$//' $file
"/127.0.0.1"}' file

回答by chown

This could also be accomplished with 1 sedcommand:

这也可以通过 1 个sed命令来完成:

**awk -F'#' '{print }' t.txt | awk 'NF > 0' | awk '{print "address=/"
address=/domain1.com/127.0.0.1
address=/domain2.com/127.0.0.1
address=/domain3.com/127.0.0.1
address=/domain5.com/127.0.0.1
"/127.0.0.1"}'**

This will modify the file in-place (creating a backup copy first), removing all lines starting with a #.

这将就地修改文件(首先创建备份副本),删除所有以#.

回答by Abhi km

It has 3 parts. Please read each to understand clearly

它有 3 个部分。请阅读每一个以清楚地理解

  1. To remove # line ----- awk -F'#' '{print $1}' t.txt
  2. To remove a blank line created by # ---- awk 'NF > 0'
  3. To print in required format. ------awk '{print "address=/"$0"/127.0.0.1"}'
  1. 删除 # 行 ----- awk -F'#' '{print $1}' t.txt
  2. 删除由 # ---- 创建的空行 awk 'NF > 0'
  3. 以所需格式打印。------awk '{print "address=/"$0"/127.0.0.1"}'

So Total Script Needed is,

所以需要的总脚本是,

awk '{ if (
[[ "$line"~="#.*" ]] && continue
!~ /^#/){printf "address=/%s/127.0.0.1 \n",##代码##}}' <your_input_file>

Output :

输出 :

##代码##

回答by louie_45

##代码##

回答by uzsolt

Maybe you can try

也许你可以试试

##代码##

Check the ~in operand!

检查~in 操作数!