awk 文件操作

发布于 2024-10-21 01:19:55 字数 464 浏览 8 评论 0原文

我的文本文件中有以下文字,我想提取如下。

device1 te rfe3 -1     10.1.2.3   device1 te rfe3
device2 cdr thr        10.2.5.3   device2 cdr thr
device4                10.6.0.8   device4
device3 hrdnsrc dhe    10.8.3.6   device3 hrdnsrc dhe

我的目标是提取设备名称和 IP 地址,并去掉其他所有内容。 设备名称后没有模式,有些有 2-3 个单词,有些没有任何内容。我也不需要第三列。我正在寻找这样的结果。

device1   10.1.2.3
device2   10.2.5.3 
device3   10.8.3.6 
device3   10.8.9.4 

这可能吗?提前致谢。

I have the following words on my text file and I want extract as follow.

device1 te rfe3 -1     10.1.2.3   device1 te rfe3
device2 cdr thr        10.2.5.3   device2 cdr thr
device4                10.6.0.8   device4
device3 hrdnsrc dhe    10.8.3.6   device3 hrdnsrc dhe

my objective is to extract the device name and the ip adrress everything else to strip away.
the is no pattern after device name some of them has 2-3 word some of them does not have any thing. also I don't need the 3rd column. I am looking the result like this.

device1   10.1.2.3
device2   10.2.5.3 
device3   10.8.3.6 
device3   10.8.9.4 

is this possible? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

终弃我 2024-10-28 01:19:57

根据垃圾与 IP 号码的接近程度,这可能会也可能不会满足您的需求:

sed -re 's/^([^ ]*).* ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1 \2/g'

Depending on how close to an IP number the cruft get, this may or may not cat your cake:

sed -re 's/^([^ ]*).* ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1 \2/g'
如梦初醒的夏天 2024-10-28 01:19:57

À 使用 perl 的 cut 解决方案,如果文件始终采用相同的列格式,则可以使用“unpack”:

perl -nE 'say unpack("A8 x14 A9")' data.txt

或者使用正则表达式获取第一个单词,后跟空格 ^ (\w+\s),然后是 . 后面的一位或多位数字 3 次 (\d+(\.\d+){3})

perl -nE '/^(?<name>\w+\s).*?(?<ip>\d+(\.\d+){3})/; 
         say "$+{name} $+{ip}" '  data.txt

:命名捕获 ($+{name} $+{ip}) 只是为了好玩:-)

À la the cut solution with perl you could use "unpack" if the file is always in the same format column wise:

perl -nE 'say unpack("A8 x14 A9")' data.txt

Or use a regular expression to get the first word followed by a space ^(\w+\s) and then one or more digits following a . 3 times (\d+(\.\d+){3}):

perl -nE '/^(?<name>\w+\s).*?(?<ip>\d+(\.\d+){3})/; 
         say "$+{name} $+{ip}" '  data.txt

The named captures ($+{name} $+{ip}) are just for fun :-)

带上头具痛哭 2024-10-28 01:19:56

Python 不在您的列表中,但类似的东西可能会起作用。

import sys
import re
pattern= re.compile( "^(\w+)\s.*?\s(\d+\.\d+\.\d+\.\d+)\s.*$" )
for line in sys.stdin:
    match= pattern.match( line )
    sys.stdout.write( "{0} {1}".format( match.group(1), match.group(2) ) )

它应该可以在大多数 Linux 平台上运行,因为 Python 已经安装了。

Python's not on your list, but something like this might work.

import sys
import re
pattern= re.compile( "^(\w+)\s.*?\s(\d+\.\d+\.\d+\.\d+)\s.*$" )
for line in sys.stdin:
    match= pattern.match( line )
    sys.stdout.write( "{0} {1}".format( match.group(1), match.group(2) ) )

It should work on most Linux platforms, since Python is already installed.

青春如此纠结 2024-10-28 01:19:56

假设输入文件的字段始终与相同的列对齐,最短的 POSIX 解决方案是

$ cut -c1-8,23-33 x
device1  10.1.2.3

device2  10.2.5.3

device4  10.6.0.8

device3  10.8.3.6

Assuming the input file has the fields always aligned to the same columns, the shortest POSIX solution would be

$ cut -c1-8,23-33 x
device1  10.1.2.3

device2  10.2.5.3

device4  10.6.0.8

device3  10.8.3.6
随心而道 2024-10-28 01:19:55
 sed -r 's/^([^ ]*) .* (([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1 \2/'

概念验证

$ sed -r 's/^([^ ]*) .* (([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1 \2/' ./infile
device1 10.1.2.3

device2 10.2.5.3

device4 10.6.0.8

device3 10.8.3.6
 sed -r 's/^([^ ]*) .* (([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1 \2/'

Proof of Concept

$ sed -r 's/^([^ ]*) .* (([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1 \2/' ./infile
device1 10.1.2.3

device2 10.2.5.3

device4 10.6.0.8

device3 10.8.3.6
牛↙奶布丁 2024-10-28 01:19:55

awk 中,这类似于

$ awk '{
         for (f = 2; f <= NF; f++) {
           if ($f ~ /^([0-9]+\.){3}[0-9]+$/) {
             print $1, $f
             break
           }
         }
       }' file

以下内容:

mress:10192 Z$ cat pffft.awk
{
  for (f = 2; f <= NF; f++) {
    if ($f ~ /^([0-9]+\.){3}[0-9]+$/) {
      print $1, $f
      break
    }
  }
}
mress:10193 Z$ cat pfft.in 
device1 te rfe3 -1     10.1.2.3   device1 te rfe3
device2 cdr thr        10.2.5.3   device2 cdr thr
device4                10.6.0.8   device4
device3 hrdnsrc dhe    10.8.3.6   device3 hrdnsrc dhe
mress:10194 Z$ awk -f pffft.awk pfft.in
device1 10.1.2.3
device2 10.2.5.3
device4 10.6.0.8
device3 10.8.3.6
mress:10195 Z$ _

In awk, this is something like

$ awk '{
         for (f = 2; f <= NF; f++) {
           if ($f ~ /^([0-9]+\.){3}[0-9]+$/) {
             print $1, $f
             break
           }
         }
       }' file

Here's a transcript:

mress:10192 Z$ cat pffft.awk
{
  for (f = 2; f <= NF; f++) {
    if ($f ~ /^([0-9]+\.){3}[0-9]+$/) {
      print $1, $f
      break
    }
  }
}
mress:10193 Z$ cat pfft.in 
device1 te rfe3 -1     10.1.2.3   device1 te rfe3
device2 cdr thr        10.2.5.3   device2 cdr thr
device4                10.6.0.8   device4
device3 hrdnsrc dhe    10.8.3.6   device3 hrdnsrc dhe
mress:10194 Z$ awk -f pffft.awk pfft.in
device1 10.1.2.3
device2 10.2.5.3
device4 10.6.0.8
device3 10.8.3.6
mress:10195 Z$ _
蒲公英的约定 2024-10-28 01:19:55

在 perl 中

perl -ne 'next if /^\s*$/ ; /^(\w+).*?(\d+(\.\d+){3})/; print "$1\t$2\n"' test_file

对于排序结果,您可能可以将输出通过管道传输到排序命令

perl -ne 'next if /^\s*$/ ; /^(\w+).*?(\d+(\.\d+){3})/; print "$1\t$2\n"' test_file | sort

更新的脚本,如版本

my $test_file = shift or die "no input file provided\n";

# open a filehandle to your test file
open my $fh, '<', $test_file or die "could not open $test_file: $!\n";

while (<$fh>) {
    # ignore the blank lines
    next if /^\s*$/;

    # regex matching
    /               # regex starts
    ^               # beginning of the string
    (\w+)           # store the first word in $1
    \s+             # followed by a space
    .*?             # match anything but don't be greedy until...
    (\d+(\.\d+){3}) # expands to (\d+\.\d+\.\d+\.\d+) and stored in $2
    /x;             # regex ends 

    # print first and second match
    print "$1\t$2\n"
}

in perl

perl -ne 'next if /^\s*$/ ; /^(\w+).*?(\d+(\.\d+){3})/; print "$1\t$2\n"' test_file

for sorted results you could probably pipe the output to sort command

perl -ne 'next if /^\s*$/ ; /^(\w+).*?(\d+(\.\d+){3})/; print "$1\t$2\n"' test_file | sort

Updated script like version

my $test_file = shift or die "no input file provided\n";

# open a filehandle to your test file
open my $fh, '<', $test_file or die "could not open $test_file: $!\n";

while (<$fh>) {
    # ignore the blank lines
    next if /^\s*$/;

    # regex matching
    /               # regex starts
    ^               # beginning of the string
    (\w+)           # store the first word in $1
    \s+             # followed by a space
    .*?             # match anything but don't be greedy until...
    (\d+(\.\d+){3}) # expands to (\d+\.\d+\.\d+\.\d+) and stored in $2
    /x;             # regex ends 

    # print first and second match
    print "$1\t$2\n"
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文