2つの二重引用符の間にsed get substringを使用する


14

ファイルがあります

xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
"/home/path/to/file1": Permission denied (13) rsync:
"/home/path/to/file2": Permission denied (13) rsync:
"/home/path/to/file3": Permission denied (13)

ここで、ファイルパスのみを抽出し、別のファイルに保存します。出力ファイルは次のようなものです。

/home/path/to/file 
/home/path/to/file1 
/home/path/to/file2
/home/path/to/file3

sedまたはawkを使用してこれを行うにはどうすればよいですか?

試しましたsed -n '/"/,/"/p' myfileが、うまくいきません。


3
閉会の投票者に—どうしてこれが話題外になるのでしょうか?それはシェルプログラミングについてです!! それがスタックオーバーフローのトピックにあるプログラミングです!
ジョナサンレフラー

2
Stack Overflowへようこそ。ご覧のとおり、完全に良い質問(このような質問)を閉じる理由が悪いので、かゆいトリガーフィンガーを閉じる人に問題があることがあります。それはそれほど頻繁に起こるわけではありません(または、私はそれほど頻繁に問題を見ることができません)が、実際には起こります。すぐよくある質問を読むことを忘れないでください。
ジョナサンレフラー

回答:


17

rsyncコマンドのstderrをawkスクリプトにパイプできます。

awk -F '"' '{print $2}' 

または、次のようなカットコマンドに:

cut -d'"' -f2

2
または、より短く:cut -d\" -f2

@AndersJohansson:カットコマンドも追加してくれてありがとう。
anubhava

ファイルパスのフィールド番号が$ 2またはf2に固定されていないことがわかるので、これは機能しないと思います。

実際、rsyncは常にstderrの間"で最初にファイルパスを書き込み"ます。
anubhava

1
@ Jam88:実際には、anubbhavaがそれを書いた方法のために動作します。フィールド区切り文字は二重引用符に設定されます。これは、最初の二重引用符(おそらく空の文字列)までのすべてが$1;であることを意味します。最初と2番目の二重引用符の間はすべて$2; そして、2番目の二重引用符の後はすべて$3$4、...)にあります。ファイル名は(明らかに)常に最初の2つの二重引用符の間にあるため、このソリューションは機能するはずです(テストしたときにも機能しました)。
ジョナサンレフラー

6

を使用してsed

sed 's/^[^"]*"\([^"]*\)".*/\1/'

それは、行の始まり、一連の非引用符、二重引用符、一連の非引用符、二重引用符、および行上のその他のものをキャプチャし、キャプチャされた素材で置き換えます。

$ sed 's/^[^"]*"\([^"]*\)".*/\1/' <<'EOF'
> xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
> "/home/path/to/file1": Permission denied (13) rsync:
> "/home/path/to/file2": Permission denied (13) rsync:
> "/home/path/to/file3": Permission denied (13)
> EOF
/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3
$

GNU sedを使用したRHEL 5 Linuxでテストしますが、UNIXの7th Edition UNIX™バージョンで機能する機能のみを使用してsedください。

ちなみに、もう少し簡単な方法は、2つの代替コマンドを使用することです。最初の二重引用符までのすべてを空の文字列に変更します(これは、二重引用符が続く0個以上の非引用符のシーケンスです)。現在の最初の二重引用符の後をすべて無に変更します。

sed 's/^[^"]*"//; s/".*//'

ちなみに、試してみたコマンド( `sed -n '/" /、/ "/ p')は、二重引用符を含む行から二重引用符を含む次の行まで、行をまったく編集せずに印刷します。それがあなたのために動作しないように思われた理由です-それはあなたが尋ねたものを行いましたが、あなたがそれをするように頼んだことはあなたがそれをするように意図したものではありませんでした。

効率的には、パフォーマンスに測定可能な差が生じることはほとんどありません。メンテナンスの容易さの観点から、後者は脳細胞への負担が少ないと思われます。


1

のバージョンがgrepPerl-regexp をサポートしている場合:

grep -oP '(?<=")/home/.*?(?=")' file >> anotherfile

結果:

/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3

必要に応じて、倍精度の任意の値に一致させるために、これをより厳密でないものにすることもできます。

grep -oP '(?<=")[^"]*' file >> anotherfile

行の後半に余分な二重引用符がある場合に.*備え.*?て、欲張りでない人を作る必要がありますか?またはの[^"]*代わりに使用し.*ますか?
ジョナサンレフラー

-1

>>演算子を使用して、出力をファイルに保存します。

お気に入り

grep -r "pattern" * >> file.txt

sedを使用して特定のシナリオに合わせて変更します

>> filename

コマンドに


grep -r(引数にリストされている任意のディレクトリを再帰的に検索を行います*)。どのパターンを念頭に置いているかは明確ではありませんがgrep、すべてのラインを取り上げます。演習の目的は、回線の一部から情報を収集することです。GNUを使用している場合grep、それを行う方法があります(-o)。これらは非標準です(GNUが事実上の標準を定義している場合を除く)。同様に、PCRE正規表現を使用します。これらは別のGNU拡張機能です。あなたはGNU持っているなら、彼らは罰金だgrepとGNUのプラットフォーム上で作業する計画grepデフォルトでは利用できませんが。
ジョナサンレフラー

申し訳ありませんが、出力をファイルに入れるために何をすべきかを一般的に知りたいと思ったので、grepは単なる例です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.