文字列を見つけて、その行の最初の文字と最後の文字を印刷します。

文字列を見つけて、その行の最初の文字と最後の文字を印刷します。

さまざまな長さの数百行のファイルがあります。 「New」という文字列を含む各行を見つけて、最初の7文字と最後の文字の後の10番目の文字を印刷したいと思います。

例えば、 cat file1.txt

1234567 New line with irrelevant info x end line
2345678 irrelevant line
3456789 New line with different irrelevant info y end line
4567890 irrelevant line
5678901 New line with yet more irrelevant info z end line

私の結果は次のとおりです

1234567 x 
3456789 y
5678901 z

答え1

POSIX的に:

この行には少なくとも10文字が含まれていると仮定します(そうでない場合は、2行目の動作は指定されておらず、後にまたは追加してsubstr()10文字または17文字未満の行をスキップできます)。&& length >= 10&& length >= 17/New/

awk '/New/ {print substr($0, 1, 7), substr($0, length - 9, 1)}'

または、行に17文字以上が含まれているとします(そうでない行はスキップします)。

sed -n '/New/ s/^\(.\{7\}\).*\(.\).\{9\}$/\1 \2/p'

答え2

好きなものを選択してください:

awk解決策:

awk '/New/{ print substr($0, 1, 7), substr($0, length-9, 1) }' file1.txt

sed解決策:

sed -rn '/New/ s/^(.{7}).*(.).{9}$/\1 \2/p' file1.txt

出力例(両方の方法):

1234567 x
3456789 y
5678901 z

答え3

gawknullこれは、フィールド区切り文字FSと出力フィールド区切り文字を使用して操作を実行する「残忍な」ソリューションです。OFSこれは、入力ファイルのすべての文字がawkのフィールドとして扱われることを意味します。

awk '/New/{print $1,$2,$3,$4,$5,$6,$7," ",$(NF-9)}' FS="" OFS="" file1
1234567 x
3456789 y
5678901 z

grep / sedを使用するより多くの解決策が続きます。

答え4

多様性のためにbashソリューションのみが使用されます。ファイルの複数行を処理するときは、通常、sedとawkはより良いツールですが、bashは操作を完了できます。ここで、文字列スライス変数の拡張は非常に便利です。

while IFS= read -r line
do
  # Check the line length.
  # This could be whatever test defines an irrelevant line.
  if [ "${#line}" -lt "25" ]
  then
    continue
  fi

  printf '%s\n' "${line:0:7} ${line: -10:1}"
done < file1.txt

出力

1234567 x
3456789 y
5678901 z

関連情報