シェルスクリプトに無効な値があります

シェルスクリプトに無効な値があります

こんにちはプログラミング初心者です。

以下のスクリプトを実行しようとしている場合は、この形式の入力ファイルを使用してください。 (この場合はnohd*.txtファイルと呼ばれます。)

NSGEAPKNFGLDVKITGESENDRDLGTAPGGTLNDIG
IIIIMMMMMOOOOOOOOOOOOOMMMMMMMMMMMIIII

file のテキストを含む列数を計算したいと思います。d.txt次の手順をご覧ください。

D
O

これを行うには、次のスクリプトを作成しました。

#!/bin/bash
for z in {1..141}
do
        a=0
        l=$(tail -1 nohd$z.txt | wc -m)
        x=$(cat d.txt)
                for ((p; p<=l; p++))
                do
                        if [ "$(cut -c $p nohd$z.txt)" = "$x" ] ; then
                                a=$((a+1))
                                p=$((p+1))
                        fi
                done
        echo $a
done

./script 次のエラーを表示するスクリプトを使用してこのスクリプトを実行しています。

cut: invalid byte/character position ‘{1..351}’

最初の値のみが正しく変換され、残りの値はゼロに変換されます。予想される出力は次の形式です。

5
20
4

誰でも私を助けることができますか?ありがとう

答え1

#!/usr/bin/perl

use File::Slurp;

# read d.txt and turn into a regular expression.
my $re = '^(' . join ('|',read_file('./d.txt', chomp => 1)) . ')$';

# read input files and print location of matches.
while (<>) {
  for (my $i=0;$i <= length; $i++) {
    printf "%s\n", $i+1 if (substr($_,$i,1) =~ m/$re/o);
  }
}

このPerlスクリプトは、入力行の各「D」と「O」の文字位置を印刷します。

たとえば、別の名前で保存してislem.pl実行可能にしchmod +x islem.plたら、次のように実行します。

$ ./islem.pl nohd*.txt
12
22
24
35
10
11
12
13
14
15
16
17
18
19
20
21
22

上記の出力はnohd1.txt


私はあなたの質問を誤解したと思います。欲しいと思う計算代わりに連続して一致します。場所すべてのゲーム。これが欲しいものなら、次のことを試してください。

#!/usr/bin/perl -l

use File::Slurp;

# read d.txt and turn into a regular expression.
my $re = '^(' . join ('|',read_file('./d.txt', chomp => 1)) . ')$';

# read input files and print location of matches.
while (<>) {
  my $count=0;
  for (my $i=0;$i <= length; $i++) {
    $count++ if (substr($_,$i,1) =~ m/$re/o);
  };
  print $count;
}

出力例:

$ ./islem2.pl nohd*
4
13

これは多くの変化に容易に適応する。たとえば、:その数で区切られた形式でファイル名と行番号を印刷したい場合:

#!/usr/bin/perl -l

use File::Slurp;

# read d.txt and turn into a regular expression.
my $re = '^(' . join ('|',read_file('./d.txt', chomp => 1)) . ')$';

# read input files and print location of matches.
while (<>) {
  my $count=0;
  for (my $i=0;$i <= length; $i++) {
    $count++ if (substr($_,$i,1) =~ m/$re/o);
  };
  print "$ARGV:$.:$count";
} continue {
  # explicitly close the current file on eof to reset the line counter
  # after each input file because perl only has a cumulative line
  # counter ($.) rather than both FR and FNR like awk.
  close ARGV if eof;
}

出力例:

$ ./islem3.pl nohd*.txt
nohd1.txt:1:4
nohd1.txt:2:13

関連情報