web-dev-qa-db-ja.com

ファイルの特定のテキストのみを別のテキストにコピーする

私は内容がファイル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
6
gkmohit

ファイルは同じパターンに従っていると思います。その場合は、次のようなコマンドを使用できます。

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
8
Ramesh

awkによる簡単なアプローチ:

awk -F\" '/WOF/ {print $4}' abc.txt > outfile
  • -F\"は、フィールド区切り文字をデフォルト(スペース)から引用符(\でエスケープ)に変更します
  • /WOF/は、各レコード(ファイルの行)の返される結果を、パターンに一致するものに制限します:WOF
  • $4は、一致する各レコードの4番目のフィールドであるパスです。
7
jasonwryan

Grepとcutによる別のアプローチ:

grep "kind=\"con\"" sample.txt | cut -d \" -f 4 > sample_edited.txt

これにより、kind="con"を含むすべての行がgrepさ​​れ、cutの区切り文字を"に設定してパスが出力されます。

4
Glutanimate
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 [〜#〜] ...のものだけを取得するはずです。また、完全にポータブルです。

4
mikeserv

sed

sed -e 's/.*path="//' -e 's:"/>$::' abc.txt > output_file
2
iruvar

まだ誰も投稿していないので、Perlソリューションをいくつか紹介します。

Perl -ne  's/.*con.*="(.+)".*/$1/ && print' file

説明

-neは、「入力ファイルを1行ずつ読み取り、-eから渡されたスクリプトを適用する」という意味です。 s/foo/bar/は置換演算子であり、foobarに置き換えます。この場合、置換は括弧内で一致したものになります。これは$1です。正規表現は、「conまでのすべてを照合し、次に=までの最も長い文字列を照合し、引用符の間のすべてをキャプチャします。&& printは、置換が成功した。

Perl -e  'print grep{s/.*con.*=.(.+)".*/$1/}<>' file

説明

これはもう少し慣用的です。上記と同じ置換を入力ファイル(<>)の各行に適用した結果を出力します。同じ基本的なアプローチを書くためのちょうど異なる方法。

Perl -F'[="]' -lane 'print $F[5] if $F[2]=~/con/' file

説明

-aPerlawkのように動作させ、入力行をフィールドによって(@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に保存します。次に、$bconと一致する場合、最後の3文字が$cから削除され、結果が$aとして保存され、最初の文字(引用符)とともに印刷されます。削除されました。 bashの文字列操作オプションの詳細については here を参照してください。

2
terdon

あなたはこのようにそれを行うことができます:

while IFS=\" read -r _ _ _ f4 _; do
    case $f4 in
        */*) echo "$f4";;
    esac
done < file
1
John B

そして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
1
Avinash Raj