特定の行を抽出して最初の行bashに入れます。

特定の行を抽出して最初の行bashに入れます。

行に特定の文字(「|」など)が含まれている場合は、その行を抽出して最初の行に入れるにはどうすればよいですか。

たとえば、


varl="This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
this row contains I|am|sepcific|
...
This is the last row (I might be specific)
"

出力は次のようになります。


varl="this row contains I|am|sepcific|
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)
"

特定の行はどの行にも表示できます。

私がしたことは少し混乱し、正しい結果が得られませんでした。

new_varl=`echo "$varl" | grep '|'`\n`echo "$varl" | grep -v '|' `

しかし、結果は次のようになります。

new_varl="this row contains I|am|sepcific|\nThis is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)"

\nキャリッジリターン文字としては使用できません。

答え1

\nキャリッジリターン文字ではなく、改行文字です。キャリッジリターン文字はYes、\r改行文字はプラットフォームに応じて、または\nまたはです。 Unixでは。\r\n\n\r\n

改行で区切られたテキストでは、改行が見つかりません。 grepは一度に1行に正規表現を適用し、定義によっては改行で他の行と区別されるため、改行を含めることはできません。

awkを使用してください。

awk '/\|/{ print; next } { tail=tail $0 ORS } END{ printf "%s", tail }'

たとえば、

$ echo "$varl"
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
this row contains I|am|sepcific|
...
This is the last row (I might be specific)

$ varl=$( echo "$varl" | awk '/\|/{ print; next } { tail=tail $0 ORS } END{ printf "%s", tail }' )

$ echo "$varl"
this row contains I|am|sepcific|
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)

答え2

コマンドの問題は、過度に複雑であること(長いパイプとネストされたバックティック)に加えて、nコマンドとして使用しようとし、echo場合によってはそれを使用すると、出力されるデータが変更される可能性があることです。

これは、値をvarl含むすべての行に置き換えられ、|その後に含まれていないすべての行が置き換えられます|

varl=$( grep    -F '|' <<<"$varl"
        grep -v -F '|' <<<"$varl" )

または

varl=$( grep -F '|' <<<"$varl"; grep -v -F '|' <<<"$varl" )
  • この-Fオプションを使用すると、パターン式grepは(正規表現ではなく)文字列として扱われます。
  • <<<"..."これは「here-string」という他のシェルの非標準機能です。bashコマンドの標準入力ストリーム内のコマンドに指定された文字列を提供します。標準的な代替案で入力をパイプする必要がありますprintf '%s\n' "$varl"が、そうしないでくださいecho "$varl"(参照なぜprintfがechoより優れているのですか?)。
  • 無条件に順番に実行する必要がある2つのコマンドは、リテラルの改行または区切り文字で区切ることができます;

\n試しているコマンドをもう一度見てみると(ただし、表示された出力は生成されません)、2つのecho+パイプgrep間の区切り文字として使用しようとしているようです。上記のように;置換またはリテラルの改行を使用してください。

答え3

new_varl=`echo "$varl" | grep '|'`$'\n'`echo "$varl" | grep -v '|' `

答え4

引用符で囲みます。

new_varl=`echo "$varl" | grep '|'`"\n"`echo "$varl" | grep -v '|' `
echo "$new_varl"

このような操作では、中間変数を使用することをお勧めします。

var_s=`echo "$varl" | grep '|'`
var_ns=`echo "$varl" | grep -v "$var_s"`
new_varl="$var_s\n$var_ns"

読んで維持するのは簡単です。もちろん、好みの問題ですが、コードの行にある特定のエラーは簡単に気付いて修正できます。

関連情報