linux - 在 bash/shell 中的关键字后添加文本

标签 linux bash shell awk

我正在从 MSoft 迁移 PTR 记录,我正在根据需要调整区域文件。我已经准备好区域文件,它们如下所示:

snapo@jump:~/mike/10$ cat 21.128

102                     [AGE:3630582]   1200    PTR     host1.domain.company.local.                      
69                      [AGE:3630774]   1200    PTR     host2.domain.compan2.local.                    
                        [AGE:3630762]   1200    PTR     host2.domain.company.local.                          
80                      [AGE:3630774]   1200    PTR     hostXX.domain.company.local.  

所以我将文件名作为变量 x 我想用 awk 实现文本文件的输出(因为我不认为 bash 中有另一种方法) .请不要使用 php/python/perl 回答,因为脚本需要在不同的系统上运行,并且应该安装的唯一语言是 bash。 因为这是从多个 PTR 区域合并到一个区域,所以我必须将区域文件编辑为如下所示:

102.21.128                        [AGE:3630582]   1200    PTR     host1.domain.company.local.                      
69.21.128                         [AGE:3630774]   1200    PTR     host2.domain.compan2.local.                    
21.128                            [AGE:3630762]   1200    PTR     host2.domain.company.local.                          
80.21.128                         [AGE:3630774]   1200    PTR     hostXX.domain.company.local.  

也有可能是第一行没有数字"empty",那么应该加上前面没有点号的。您有 awk 示例或任何其他示例(cut、grep、head、tail、sed)吗? 命令应替换现有文件中的字符串或用输出文件 > editedtextfile.txt 或类似文件中的管道替换。

最佳答案

使用 sed:

 sed 's/^[^[:space:]]\+/&.21.128/' filename

将输入视为纯文本具有保持格式完整的优点。

对于编辑后的问题,这可以扩展为

sed 's/^[^[:space:]]\+/&.21.128/; s/^[[:space:]]/21.128&/' filename

补充:如果不想在代码中重复插入的数据,那么

sed 's/^[^[:space:]]*/&\n21.128/; s/^\n//; s/\n/./' filename

是另一种使用更多技巧的方法:它在新数据之前插入一个标记,如果之前没有任何内容,则删除标记,否则用点替换它。

附录 2: 在 sed 代码中使用 shell 变量有点棘手并且有潜在危险(因为代码注入(inject))。如果变量来自可靠来源并且已知不包含任何元字符,则可以编写

sed "s/^[^[:space:]]*/&\n$variable/; s/^\n//; s/\n/./" filename

正如@triplee 在评论中指出的那样。如果 $variable 包含斜杠但没有其他元字符并且已知一个字符不包含,则可以为 s 命令使用不同的分隔符:

sed "s@^[^[:space:]]*@&\n$variable@; s/^\n//; s/\n/./" filename

(如果已知$variable不包含字符@)。

如果不是这种情况,则需要更深层次的魔法。例如,如果已知 $variable 是单行(我怀疑是这种情况,否则转换毫无意义),那么可以写成

(echo "$variable"; cat filename) | sed '1 { h; d; }; s/^[^[:space:]]*/&\n/; G; s/\(.*\n\)\(.*\)\n\(.*\)/\1\3\2/; s/^\n//; s/\n/./'

这会将变量作为输入的第一行提供给 sed,然后按如下方式工作:

1 { h; d; }                        # first line: hold, don't print
s/^[^[:space:]]*/&\n/              # after that: Insert marker as before
G                                  # fetch variable from the hold buffer
s/\(.*\n\)\(.*\)\n\(.*\)/\1\3\2/   # move it to the right place
s/^\n//                            # rest as before.
s/\n/./

但是,此时您可能要考虑改用 awk,它有更好的工具来处理 shell 变量(也就是说,您可以在不将它们视为代码的情况下使用它们):

awk -v var="$variable" '{ n = match($0, /[ \t]/); print substr($0, 1, n - 1) (n <= 1 ? "" : ".") var substr($0, n) }' filename

-v var="$variable" 使变量 var 为 awk 代码所知,其值为 $variable" ,然后 awk 代码按如下方式工作:

{
  # find the first space or tab in the line (0 if none)
  # (I would use [[:space:]] here, but there are commonly shipped versions
  # of mawk that don't understand POSIX character classes, so for portability
  # I resort to [ \t])
  n = match($0, /[ \t]/)

  # assemble output line accordingly and print it.
  print substr($0, 1, n - 1) (n <= 1 ? "" : ".") var substr($0, n)
}

关于linux - 在 bash/shell 中的关键字后添加文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29254668/

相关文章:

linux - Perl 检查网络接口(interface)是否启动(linux)

json - 如何创建 key :value list from JSON? key 名称应包含对象本身的一些值

arrays - Bash 字符串数组

python - Linux 输出重定向守护进程不工作

linux - 我有一个 Arduino Yun,当我使用 putty (SSH) 执行 mkdir 命令时,它显示 "can' t 创建目录 : No such file or directory"

bash - 重命名文件时 bash 循环的性能

git - 在 post-update hook 中查找 Git 分支名称

linux - 如果定义了变量 1,则变量 2 必须为空,在 bash 中反之亦然

python - python如何与linux交互?

linux - bash 脚本 | URL健康检查|邮件发送选项