私は内容がファイルabc.txtを持っています
<classpathentry kind="src" path="Sources"/>
<classpathentry kind="con" path="WOFramework/ERExtensions"/>
<classpathentry kind="con" path="WOFramework/ERJars"/>
<classpathentry kind="con" path="WOFramework/ERPrototypes"/>
<classpathentry kind="con" path="WOFramework/JavaEOAccess"/>
<classpathentry kind="con" path="WOFramework/JavaEOControl"/>
<classpathentry kind="con" path="WOFramework/JavaFoundation"/>
<classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/>
すべてのパスを別のファイルにコピーしたい。つまり、出力テキストファイルを次のようにしたいのです。
WOFramework/ERExtensions
WOFramework/ERJars
WOFramework/ERPrototypes
WOFramework/JavaEOAccess
WOFramework/JavaEOControl
WOFramework/JavaFoundation
WOFramework/JavaJDBCAdaptor
ファイルは同じパターンに従っていると思います。その場合は、次のようなコマンドを使用できます。
grep -o ' path=.*$' file.txt | cut -c8- |rev | cut -c 4- | rev
したがって、cat
を使用してファイルを開き、path=
から文字のみを抽出してから、cut
を使用して不要な文字を削除し、rev
手法を使用して不要な文字を最後から削除します。
別のawkアプローチ
awk -F'path="' '{print $2}' file.txt |rev | cut -c 4- | rev
path="
を区切り文字として使用し、その後にすべての情報を出力します。また、rev
は基本的に上記と同じです。
テスト
cat file.txt
<classpathentry kind="src" path="Sources"/>
<classpathentry kind="con" path="WOFramework/ERExtensions"/>
<classpathentry kind="con" path="WOFramework/ERJars"/>
<classpathentry kind="con" path="WOFramework/ERPrototypes"/>
<classpathentry kind="con" path="WOFramework/JavaEOAccess"/>
<classpathentry kind="con" path="WOFramework/JavaEOControl"/>
<classpathentry kind="con" path="WOFramework/JavaFoundation"/>
<classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/>
コマンドを実行した後、
Sources
WOFramework/ERExtensions
WOFramework/ERJars
WOFramework/ERPrototypes
WOFramework/JavaEOAccess
WOFramework/JavaEOControl
WOFramework/JavaFoundation
WOFramework/JavaJDBCAdaptor
コメントでステファンによって提供されるより良いアプローチ。
cut -d '"' -f4 file.txt
awk
による簡単なアプローチ:
awk -F\" '/WOF/ {print $4}' abc.txt > outfile
-F\"
は、フィールド区切り文字をデフォルト(スペース)から引用符(\
でエスケープ)に変更します/WOF/
は、各レコード(ファイルの行)の返される結果を、パターンに一致するものに制限します:WOF
$4
は、一致する各レコードの4番目のフィールドであるパスです。Grepとcutによる別のアプローチ:
grep "kind=\"con\"" sample.txt | cut -d \" -f 4 > sample_edited.txt
これにより、kind="con"
を含むすべての行がgrepされ、cut
の区切り文字を"
に設定してパスが出力されます。
sed -n '/.*="con"[^"]*./{s///;s/..>//p}' <<\DATA
<classpathentry kind="src" path="Sources"/>
<classpathentry kind="con" path="WOFramework/ERExtensions"/>
<classpathentry kind="con" path="WOFramework/ERJars"/>
<classpathentry kind="con" path="WOFramework/ERPrototypes"/>
<classpathentry kind="con" path="WOFramework/JavaEOAccess"/>
<classpathentry kind="con" path="WOFramework/JavaEOControl"/>
<classpathentry kind="con" path="WOFramework/JavaFoundation"/>
<classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/>
DATA
WOFramework/ERExtensions
WOFramework/ERJars
WOFramework/ERPrototypes
WOFramework/JavaEOAccess
WOFramework/JavaEOControl
WOFramework/JavaFoundation
WOFramework/JavaJDBCAdaptor
これは[〜#〜] wo [〜#〜] ...のものだけを取得するはずです。また、完全にポータブルです。
sed
sed -e 's/.*path="//' -e 's:"/>$::' abc.txt > output_file
まだ誰も投稿していないので、Perlソリューションをいくつか紹介します。
Perl -ne 's/.*con.*="(.+)".*/$1/ && print' file
-ne
は、「入力ファイルを1行ずつ読み取り、-e
から渡されたスクリプトを適用する」という意味です。 s/foo/bar/
は置換演算子であり、foo
をbar
に置き換えます。この場合、置換は括弧内で一致したものになります。これは$1
です。正規表現は、「con
までのすべてを照合し、次に=
までの最も長い文字列を照合し、引用符の間のすべてをキャプチャします。&& print
は、置換が成功した。
Perl -e 'print grep{s/.*con.*=.(.+)".*/$1/}<>' file
これはもう少し慣用的です。上記と同じ置換を入力ファイル(<>
)の各行に適用した結果を出力します。同じ基本的なアプローチを書くためのちょうど異なる方法。
Perl -F'[="]' -lane 'print $F[5] if $F[2]=~/con/' file
-a
はPerl
をawk
のように動作させ、入力行をフィールドによって(@F
配列として保存された)フィールドに自動的に分割します。 -F
パラメータ。 =
または"
で分割するように指示しているので、5番目のフィールドは後のフィールドになり、2番目のフィールドがcon
と一致する場合にのみ出力されます。 -l
は、各print
呼び出し(および関連しない他の事項)に改行を追加します。
そしてもう1つはgrep
です。これはletters/letters
のすべての一致を出力します。例では正しく機能しますが、より複雑な例では機能しない可能性があります。
grep -Eio '[a-z]+/[a-z]+' file
純粋なシェル(bash/zsh/ksh):
while IFS='=' read a b c; do
[[ "$b" =~ "con" ]] && a=${c/%?\/>/} && echo ${a/#?};
done < file
while read; do ... ; done < file
は、ファイルの各行をループします。 IFS
を=
に設定すると、各行が=
で分割され、read a b c
は各フィールドを変数$a
から$c
に保存します。次に、$b
がcon
と一致する場合、最後の3文字が$c
から削除され、結果が$a
として保存され、最初の文字(引用符)とともに印刷されます。削除されました。 bashの文字列操作オプションの詳細については here を参照してください。
あなたはこのようにそれを行うことができます:
while IFS=\" read -r _ _ _ f4 _; do
case $f4 in
*/*) echo "$f4";;
esac
done < file
そしてGNU sedの後方参照を通じて
sed -nr 's/^.*kind=\"con\" path=\"([^"]*)\".*$/\1/p' file
例:
$ cat aa
<classpathentry kind="src" path="Sources"/>
<classpathentry kind="con" path="WOFramework/ERExtensions"/>
<classpathentry kind="con" path="WOFramework/ERJars"/>
<classpathentry kind="con" path="WOFramework/ERPrototypes"/>
<classpathentry kind="con" path="WOFramework/JavaEOAccess"/>
<classpathentry kind="con" path="WOFramework/JavaEOControl"/>
<classpathentry kind="con" path="WOFramework/JavaFoundation"/>
<classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/>
data
$ sed -nr 's/^.*kind=\"con\" path=\"([^"]*)\".*$/\1/p' aa
WOFramework/ERExtensions
WOFramework/ERJars
WOFramework/ERPrototypes
WOFramework/JavaEOAccess
WOFramework/JavaEOControl
WOFramework/JavaFoundation
WOFramework/JavaJDBCAdaptor