cut
を使用してCSVファイルの指定された列を切り取る方法と同様に、テキストからキーと値のペア(キーが一意で指定されている)を切り取る簡単な方法を探しています。私が探しているキーは、常に行内の同じ相対位置にあるとは限りません。つまり、cut
の後にsed
を続けても、うまくいきません。 mの検索は、常に同じ,
区切りの列にあるとは限りません。
問題のテキストは確かにCSVですが、値が=
で区切られたキーと値のペアである場合があります。
たとえば、次の3行でファイルを解析するとします。
Foo=1, Bar=2, Baz=3
Bar=4, Foo=2, Baz=3
Bar=42, Baz=42, Foo=3
そして、私はこのテキストをカットして、特定のキーのキー/値ペアを生成したいと思います。 Foo
を探していた場合、希望する出力は次のようになります。
Foo=1
Foo=2
Foo=3
理想的には、cut
と同様の構文を持ち、stdinとファイルの両方から読み取ることができるコマンドラインツールが欲しいです。
そのようなツールはありますか?
grep
は-o
オプションでこれを行うことができます:
grep -o 'Foo=[^,]*' file
選択肢のリストを切り上げるawk
ソリューション:
awk -v RS=', ' -F'=' '$1=="Foo"' <file>
各レコードを', '
で区切るように扱い、各レコードを=
文字のフィールドに分割します(-F
を使用)。次に、最初のフィールド$1
を照合するだけです。ここに示す提案は、単純な文字列マッチングです。正規表現を自由に使用してください。 $1~/\<Foo\>/
。
実際の状況の複雑さに応じて、次のsed
コマンドで十分な場合があります。
sed -n 's/^.*\(\<Foo=[^,]*\).*/\1/p'
これが実際の例です
FIELD='Foo'
sed -n "s/^.*\(\<${FIELD}=[^,]*\).*/\1/p' << xxEOFxx
Foo=1, Bar=2, Baz=3
Bar=4, Foo=2, Baz=3
Bar=42, Baz=42, Foo=3
xxEOFxx
Foo=1
Foo=2
Foo=3
あなたの例を考えると、もろい解決策はcut
を含むことができます:
tr ', ' '[\n*]' <input | cut -sd F -f1-
...各キー/値のペアを別々の行に配置し、間にあるカンマとスペースをtr
ansで\n
ewlinesに変換し、次に、含まない行をcut
tingアウトします。 F
。しかし、これは非常に特殊な例であり、F
が必要なキーと値のペアでのみ発生することが確実な場合にのみ機能します。
それ以外の場合、sed
は私が使用するものです。
sed 'y/ ,/\n\n/;/^Foo=/P;D' <input
これはまた、介在するカンマとスペースを\n
ewlinesにtr
ansformしますが、P
rintは、文字列Foo=
で始まるキー/値のペアのみを_intします。スペースが信頼できるセパレーターである限り、上記はFoo
キー/値のペアを可搬性のある方法でそれぞれ別の行に出力し、入力行で何回発生しても他に何も出力しません。 -印刷したいキー/値が含まれていない行でも。
_ [で使用できるgrep
がない場合、-o
オプション、これはトリックも行うべきです:
sed -e 's/, /\n/g' | grep '^Foo='
これは、sed
を使用して、すべてのコンマ+スペースを改行で置き換え(各キーと値のペアを独自の行に分割)、次にgrepを使用して「Foo」キーのみを検索します。
テストケース:
printf "%s\n" "Foo=1, Bar=2, Baz=3" "Bar=4, Foo=2, Baz=3" "Bar=42, Baz=42, Foo=3" \
| sed -e 's/, /\n/g' | grep '^Foo='