ファイルの各行の末尾で特定の文字/文字列を見つけ、最後の行を除いて欠落している場合は、その文字を追加するにはどうすればよいですか?

ファイルの各行の末尾で特定の文字/文字列を見つけ、最後の行を除いて欠落している場合は、その文字を追加するにはどうすればよいですか?

最後の行を除くすべての行の末尾に特定の文字/文字列が必要なファイルがあります。各行の末尾で対応する文字/文字列を検索し、存在しない場合は、追加するシェルスクリプトを使用してこれを達成できますか?

たとえば、ファイルの内容は次のようになります。

hello1
hello
hell1
hel
end

最後の行を除くすべての行の末尾に文字1がなければならず、スクリプトの出力は次のようになります。

hello1
hello1
hell1
hel1
end

sedやawkを使って書くことができるようですが、どのように機能するのかわかりません。よろしくお願いします。

答え1

1つのアプローチは次のとおりです。

 sed -e '
    s/1$/&/;t
    $!s/$/1/
' file 
sed -e '
  $q; /1$/!s/$/1/
' file

または:

sed -e '$!{/1$/!s/$/1;}'

または空白行がない場合:

sed -e '$!s/[^1]$/&1/' 

答え2

別のオプション:

sed '$!s/1\{0,1\}$/1/'

(一部のsed実装は非標準の代替を\?サポートしています\{0,1\})。

sedまたは、サポートされている実装と同じ拡張正規表現-E(まもなく標準になる予定):

sed -E '$!s/1?$/1/'

つまり、(!)最後の()を除くすべての行で、オプションの$\{0,1\}/ ?)末尾()を()に$置き換えます。11

答え3

すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ awk 'NR>1{print p 1} {sub(/1$/,""); p=$0} END{print p}' file
hello1
hello1
hell1
hel1
end

答え4

(sedから)次のことができます。

  1. 1存在するすべての場所から削除してください。s/^\(.*\)1$/\1/
  2. その後、すべての行に再度追加します。 s/.*/&1/
  3. ただし、最後の行ではない行についてのみ$!{…}
sed '$!{s/^\(.*\)1$/\1/;s/.*/&1/}' file

または、何もキャプチャしたくない場合は(アスタリスクなし)、次のいずれかを実行します。

sed '$!{s/1$//;s/$/1/}' file
sed '/1$/b;$!s/$/1/' file

関連情報