Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种方法可以对bash中括号内的数字进行操作?_Bash_Perl_Unix_Awk - Fatal编程技术网

有没有一种方法可以对bash中括号内的数字进行操作?

有没有一种方法可以对bash中括号内的数字进行操作?,bash,perl,unix,awk,Bash,Perl,Unix,Awk,我有一个输入文件和一些行的格式- 此处任意文本{{x1 x2}{x3 x4}}此处任意文本 其中,x1、x2、x3和x4为浮点数和/或整数。有没有办法,比如说,通过使用awk/perl/bash脚本,将这些数字(总是用大括号括起来)翻一番 我尝试使用下面的变体,但我对awk是新手,甚至无法在花括号中分离出数字- awk-F(“{gsub({})”,“,$NF);打印$NF}” 范例- 输入: 任意文本1此处{{1 2}{3 4}}任意文本1此处 任意文本2此处{{2.0 4}{6.0 8}}任意

我有一个输入文件和一些行的格式-

此处任意文本{{x1 x2}{x3 x4}}此处任意文本

其中,x1、x2、x3和x4为浮点数和/或整数。有没有办法,比如说,通过使用awk/perl/bash脚本,将这些数字(总是用大括号括起来)翻一番

我尝试使用下面的变体,但我对awk是新手,甚至无法在花括号中分离出数字-

awk-F(“{gsub({})”,“,$NF);打印$NF}”

范例-

输入:

任意文本1此处{{1 2}{3 4}}任意文本1此处

任意文本2此处{{2.0 4}{6.0 8}}任意文本2此处

这里是任意文本2P5

任意文本3此处{{36}{9 12}任意文本3此处

任意文本4此处{{4 8}{12 16}任意文本4此处

输出:

任意文本1此处{{2 4}{6 8}任意文本1此处

任意文本2此处{{4.0 8}{12.0 16}任意文本2此处

这里是任意文本2P5

任意文本3此处{{6 12}{18 24}任意文本3此处

任意文本4此处{{8 16}{24 32}任意文本4此处


下面是Ruby中的一个示例

$ echo "Arbitrary text here {{1.22 -3.55} {6.77 1e66}} arbitrary text here" | 
  ruby -lane 'p $_[/^[^{]*/] << 
                    $_[/{.*}/].gsub!(/[^ {}]+/) {|f| f.to_f*2} <<
                    $_[/[^}]*$/]'
"Arbitrary text here {{2.44 -7.1} {13.54 2.0e+66}} arbitrary text here"
这里的两种方法都是处理开头的
{
和结尾的
}
作为“查找浮点并用它做点什么”行为的开始。例如,没有对平衡大括号的解析。在这种情况下,如果是独立的,Perl和Ruby都会将非数字视为
0.0
,如果是在一个数字串中,则将数字终止:

$ echo "Arbitrary text here {{1.22 -3.55 aa} {6s.77 1ye66}} arbitrary text here" | 
perl -lane '$lh = $1 if m/(^[^{]*)/; 
            $rh = $1 if m/([^}]*)$/;
            $tgt = $1 if m/(\{.*\})/;
            $tgt =~ s/([^{} ]+)/$1*2/ge;  # the "e" executes the sub as Perl code
            print "$lh$tgt$rh\n";'
Arbitrary text here {{2.44 -7.1 0} {12 2}} arbitrary text here
这可能是也可能不是一个特征


随着您的更新。对整数也很有效:

$ echo "Arbitrary text1 here {{1 2} {3 4}} arbitrary text1 here
Arbitrary text2 here {{2 4} {6 8}} arbitrary text2 here
Arbitrary text2p5 here
Arbitrary text3 here {{3 6} {9 12}} arbitrary text3 here
Arbitrary text4 here {{4 8} {12 16}} arbitrary text4 here" | 
perl -lane '$rh=$lh=$tgt="";
        $lh = $1 if m/(^[^{]*)/; 
        $rh = $1 if m/([^}]*)$/;
        $tgt = $1 if m/(\{.*\})/;
        $tgt =~ s/([^{} ]+)/$1*2/ge;  # the "e" executes the sub as Perl code
        if ($rh && $lh && $tgt) {
            print "$lh$tgt$rh" ; 
        } else {
            print $_;    
        }'
Arbitrary text1 here {{2 4} {6 8}} arbitrary text1 here
Arbitrary text2 here {{4 8} {12 16}} arbitrary text2 here
Arbitrary text2p5 here
Arbitrary text3 here {{6 12} {18 24}} arbitrary text3 here
Arbitrary text4 here {{8 16} {24 32}} arbitrary text4 here

您可以捕获所需的模式,并使用它们的替换项重写字符串

这里有一个基本的方法:首先捕获组件,处理它们,然后重新组装

use warnings;
use strict;

my $str = 'Arbitrary text here {{1 2} {3 4}} arbitrary text here';

my @parts = $str =~ /(.*?){{(\d+) (\d+)} {(\d+) (\d+)}}(.*)/;

# If we expect only lines in the above format test and handle the error
if (@parts != 6) {
    die "Didn't find expected patterns in: $str";
}

my $pre_text  = shift @parts;
my $post_text = pop @parts;

my ($r1, $r2, $r3, $r4) = map { $_*2 } @parts;

my $result = $pre_text . "{{$r1 $r2}{$r3 $r4}}" . $post_text;

print $result, "\n";
代码假定输入的格式如图所示。这种“手动”分步方法的一个优点是更容易根据需要调整流程的每个部分


这可以在一个正则表达式中完成。由于盲目相信预期的数据格式通常是一个非常糟糕的主意,我们可以将替换代码放入子正则表达式中, 因此,可以根据需要更轻松地检查和处理匹配项

sub repl {
    my @nums = @_;
    die "Expected four numbers, got: @nums" if @nums != 4;

    my ($r1, $r2, $r3, $r4) = map { $_ * 2 } @nums;    

    return "{{$r1 $r2} {$r3 $r4}}";
}

$str =~ s/{{(\d+) (\d+)} {(\d+) (\d+)}}/repl($1, $2, $3, $4)/e;
这也大大清理了正则表达式本身

如果模式不匹配,则不会发生任何事情,
$str
保持不变。如果我们只希望使用此格式的行,则可能需要了解匹配失败的情况。了解此情况的一种方法是

if (not $str =~ s/.../) { warn "Failed match on: $str" }
因为替换运算符
s/
返回所进行的替换的数目


更新提供的输入示例

上面的单个正则表达式方法,带有一个带有输入行的文件
input.txt

use warnings;
use strict;

my $file = 'input.txt';
open my $fh, '<', $file  or die "Can't open $file: $!";

while (<$fh>) {
    s/{{(\d+) (\d+)} {(\d+) (\d+)}}/repl($1, $2, $3, $4)/e;
    print;
}

sub repl {
    my @nums = @_; 
    die "Expected four numbers, got: @nums" if @nums != 4;
    my ($r1, $r2, $r3, $r4) = map { $_ * 2 } @nums;    
    return "{{$r1 $r2} {$r3 $r4}}";
}
使用警告;
严格使用;
my$file='input.txt';

打开我的$fh,'你是否在寻找一些可以在花括号内找到数字的东西,这些数字可能是嵌套的,然后每个数字都翻倍?请你的问题显示一些示例输入和所需输出。是的,一般来说这是可能的,但如果没有具体的示例说明你想要实现什么,这不是一个任务这是一个很好的答案。谢谢,我添加了一个具体的例子。你的例子不是浮点数。那些是整数。
use warnings;
use strict;

my $file = 'input.txt';
open my $fh, '<', $file  or die "Can't open $file: $!";

while (<$fh>) {
    s/{{(\d+) (\d+)} {(\d+) (\d+)}}/repl($1, $2, $3, $4)/e;
    print;
}

sub repl {
    my @nums = @_; 
    die "Expected four numbers, got: @nums" if @nums != 4;
    my ($r1, $r2, $r3, $r4) = map { $_ * 2 } @nums;    
    return "{{$r1 $r2} {$r3 $r4}}";
}
Arbitrary text1 here {{2 4} {6 8}} arbitrary text1 here Arbitrary text2 here {{4 8} {12 16}} arbitrary text2 here Arbitrary text2p5 here Arbitrary text3 here {{6 12} {18 24}} arbitrary text3 here Arbitrary text4 here {{8 16} {24 32}} arbitrary text4 here