var
以下を含む変数があります。
XXXX YY ZZZZZ\n
aaa,bbb,ccc
私が望むのはaaa
2行目だけです。私は試した:
out=$(echo "$var" | awk 'NR==2{sub(",.*","")}' )
しかし、何の結果も得られません。 FSで試してみましたが、,
構文を正しく取得できませんでした。私は本当にawk / regexの構文を学びたいです。
印刷以外の場所で "$out"変数としてoutを使用したいと思います。
答え1
正規表現をしたくありません。要点はawk
自動的に行を複数のフィールドに分割することなので、フィールド区切り記号を に設定し、,
2行目の最初のフィールドを印刷するだけです。
$ printf '%s' "$var" | awk -F, 'NR==2{print $1}'
aaa
またはシェルがそれをサポートしている場合<<<
:
$ awk -F, 'NR==2{print $1}' <<<"$var"
aaa
期待どおりに使用せずに手動で実行するには、awk
次のようにします。
$ awk 'NR==2{sub(/,.*/,""); print}' <<<"$var"
aaa
awk
印刷する内容を指定していないため、結果は出ません。
答え2
${param#pattern}
または、ここで${param%%pattern}
標準パラメータ拡張演算子を使用できます。
NL='
'
out=${var#*"$NL"} # removes first line. Assumes there are at least 2
out=${out%%"$NL"*} # removes all but the first line
out=${out%%,*} # removes everything after the first ,
または、bash
具体的には次のものを使用できます。
LC_ALL=C # needed to accept non-text
[[ $var =~ ^[^$'\n']*$'\n'([^,$'\n']*) ]]
out=${BASH_REMATCH[1]}
標準的には以下もありますexpr
。
NL='
'
out=$(LC_ALL=C expr "x$var" : "[^$NL]*$NL\([^,$NL]*\)")
awk
アプローチの問題は、印刷する内容を話さないことです。awk
何も印刷されないと、$(...)
内部コマンドの出力に展開されたときに変数に何も保存されません。また、echo
任意のデータを印刷するために使用できないことを覚えておいてください。
out=$(printf '%s\n' "$var" | awk 'NR == 2 {sub(",.*", ""); print}')
または:
out=$(printf '%s\n' "$var" | awk -F, 'NR == 2 {print $1}')
1 減算 末尾改行、出力に NUL バイトが含まれている場合の動作はシェル実装ごとに異なります。
答え3
別のオプションは、次のものを使用することですsed
。
sed -n 's/,.*$//p' <<< "$var"
- これにより、
s/../../
各行の最初の行から,
行の終わりまで()までの,.*$
すべての項目()が「なし」に変わり、その部分のみが残ります。今後最初の,
。 - このオプションを使用すると、デフォルトで
-n
出力が抑制されます。p
プログラムの最後にあるコマンドは、まだsed
「検索」パターンが見つかった行を印刷します。このようにして、私たちは最初の行(なし)を無視し、実際に,
aが見つかった2行目だけを処理します。,
通常どおり、コマンド置換を使用して結果をシェル変数にインポートできます。
out=$(sed -n 's/,.*$//p' <<< "$var")
またはここで文字列を理解していないシェルでは、
out=$(printf '%s' "$var" | sed -n 's/,.*$//p')
極端なケースの例は含まれていないので、それに対応するソリューションを設計することは困難です。現在のソリューションでは、最初のフィールドを抽出する$var
行が1つしかないと想定しています。,
答え4
使用sed
:
$ sed -n '2s/,.*//p' <<<"$var"
aaa
特に、大容量ファイルを読み取る場合は、コマンド実行の2行目の後にブレークポイントを設定することをお勧めします。
$ sed -n '2{s/,.*//p;q;}' infile
これはq
後で入力ファイルを処理するのに役立ちます。