「改行までtmpと前行」を印刷したいです。私はUnixを初めて使用します。
たとえば、次のようになります。
AAA
CBH
VFh
GFD
DFC
VGF
HGD
TMP
JHG
TFD
PI1
98A
TMP
TMP
765
UBS
私が望む出力は次のようになります
GFD
DFC
VGF
HGD
TMP
TFD
PI1
98A
TMP
TMP
答え1
使用awk
:
$ awk -v RS='' -v ORS='\n\n' 'match($0,".*TMP") { print substr($0,1,RLENGTH) }' file
GFD
DFC
VGF
HGD
TMP
TFD
PI1
98A
TMP
TMP
これは、1つ以上の空行で区切られた行セットを1つのレコードとして扱います。レコードが正規表現と一致すると、一致する.*TMP
部分の後のビットが削除され、レコードの残りの部分が印刷されます。
TMP
正規表現を現在のレコードと.*TMP
一致させ、その式に一致するビットのみを印刷して、substr()
最後の発生以降のビットを削除できます。正規表現はレコードの先頭から最後のレコードまで一致し、関数はTMP
変数match()
をRLENGTH
一致長に設定します。
出力レコード区切り文字として二重改行文字を使用するため、出力の末尾に追加の空行が表示されます。
ファイルが次の場合
AAA
CBH
VFh
GFD
DFC
VGF
HGD
tmp/some/path/here
JHG
TFD
PI1
98A
tmp/some/path/here
tmp/some/path/here
765
UBS
...で始まる行に基づいて同じタイプの変換を実行し、コマンドtmp
で使用されている正規表現を変更して、末尾のmatch()
「-line」までの改行と一致するようにしますtmp
。
$ awk -v RS='' -v ORS='\n\n' 'match($0,".*tmp[^\n]*") { print substr($0,1,RLENGTH) }' file
GFD
DFC
VGF
HGD
tmp/some/path/here
TFD
PI1
98A
tmp/some/path/here
tmp/some/path/here
awk
状況がどうか100%確信できないことを参考にしてください。しなければならない\n
括弧式内で解釈されますが、awk
私がアクセスできるすべての実装(OpenBSD awk
、OpenBSD mawk
、およびGNE awk
)はこれを改行文字として扱うようです。いいえ2つの別々の文字で\
とn
。
答え2
テキストを反転して正規表現から正規表現に正常に印刷し、逆の順序で元の順序を取得します。
tac < file.txt | sed -n '/TMP/,/^$/p' | tac
答え3
最初のものを一致させることができればTMP
。空の場合、RS
2つ以上の連続した\n
文字がレコード区切り文字として使用される段落モードになります。
$ # sub is used to remove everything after first occurrence of TMP
$ # return value of sub (0 if no match, 1 if match is found) determines
$ # if record should be printed or not
$ # use \nTMP\n to match only whole line
$ awk -v RS= 'sub(/TMP\n.*/, "TMP\n")' ip.txt
GFD
DFC
VGF
HGD
TMP
TFD
PI1
98A
TMP
最後まで必要ならTMP
( GNU awk
because of gensub
) またはperl
$ # use \nTMP\n to match only whole line
$ # same as: perl -00 -ne 'print if s/.*TMP\n\K.*/\n/s' ip.txt
$ awk -v RS= '/TMP/{print gensub(/(.*TMP\n).*/, "\\1", 1)}' ip.txt
GFD
DFC
VGF
HGD
TMP
TFD
PI1
98A
TMP
TMP
答え4
タグ付けにはsedを使用したので、示されているように実行できます。私たちはGNU sedを使用しています。私が理解したところによれば、テキストファイルの各段落でtmp(小文字)で始まる最後の行以降のすべての内容を削除しようとしています。段落は、空白ではなく行で構成される島で、少なくとも1つの空行で次のインスタンスと区別されます。
sed -e '
/./{H;$!d;}
x;/\ntmp/!d
:chop
/\ntmp[^\n]*$/!s/\n[^\n]*$//
t chop
' file
段落を蓄積します。境界(空行またはeof)に達すると、短絡チェックを開始します。改行の先頭にtmpが表示されない場合は、このセクションをすぐに削除してください。それ以外の場合は、para 処理を中断して印刷する tmp 行が表示されるまで、para の末尾で行を切り捨て始めます。
GNU awk を使用して tge 段落モードで動作し、入力フィールド区切り文字を改行文字に設定します。最後から始めてフィールドを確認してください。 tmp で始まるフィールドが表示されたら、そのフィールドにパラを絞り込み、印刷して段落を完成させます。
awk -F '\n' -v RS= -v OFS='\n' '
/(^|\n)tmp/ {
for(i=NF; i; i--) {
if ($i ~ /^tmp/) {
NF=i; NF++; print; break
}
}
}
' file
rindex は、文字列内の部分文字列が最後に始まる場所を示します。したがって、rindex abdを介して最後のtmpの位置を取得し、その位置を使用して次に最も近い改行位置を取得します。
perl -p00e '
s/.*//s,next unless /^tmp/m;
s/\z/\n/;
my $p = 1+rindex($_, "\ntmp");
my $q = 1+index($_, "\n", $p);
substr($_, $q) = "\n";
' file