複数の「sed」コマンド(「;」で区切られた)を実行する方法と同様に、「awk -F」を使用してこれを実行できますか?複数の「awk」では動作しますが、「awk-F」では動作しません。

複数の「sed」コマンド(「;」で区切られた)を実行する方法と同様に、「awk -F」を使用してこれを実行できますか?複数の「awk」では動作しますが、「awk-F」では動作しません。

複数のパイプを使用せずにsedを複数回呼び出すことができます。 cmdを次のように区切ります。 (すべてありがとう...)複数のcmd;にこれを使用する方法はありますか?awk -F

sedマルチパイプの使用


echo "'text';" | \
sed s"#';##"g  | \ 
sed s"#'##"g   

text

区切り記号sedとして使用;


echo "'text';" | \
sed "            \
  s#';##g;       \
  s#'##g         \
"

text

編集する:

したがって、awk.dllを使用して複数のcmdに参加できます;。しかし、awk -F複数のcmdではこれを行うことはできません。

問題は複数の awk -Fコマンドをリンクすることですが、まだ答えはありません。

背景


# '/x/ gives the href of the actual videos
# awk -F '/x/' '{print$2}’ 
# because the /x/ is unique to the video urls
# after this the video links appear
# but I have to get rid of stuff 
# on the right of them so I do 
# awk —F 'title' '{print$1}' 
# this returns all the video links 
# but they have a double quotes 
# and a semi colon on the end.

curl -s                                 \
  https://site.com/plist/page={0..50} | \
grep '/x/'                            | \
awk -F '/x/' '{print$2}'              | \
awk -F 'title' '{print$1}'            | \
sed '                                   \
  s#";##g;                              \
  s#"##g                                \
'

これで、多くのビデオリンクがあり、ビデオダウンロードリンクを取得するために追加の処理を実行し、mapfileダウンロードリンクを配列にインポートしてparallelダウンロードするために使用します。

このコード例では、実際に実行される作業を大幅に短縮しました。

編集する:

だからこれはできません。このユーザーに深く感謝します。

このユーザーはsed私の特定のケースではこれが必要ではないと言いましたが、awk -F少なくとも20の異なるケースがあります。しかし、これは私に考える距離を与え、私がこのことをする理由は、awk -Fsed正規表現を全く知らなくても私に必要なものを提供するからです。

とにかくみんなありがとうございます。

ありがとう

@StèphaneChazelasに彼らの意見が私の問題を解決しました。

答え1

修正する:問題は実質的な変化この回答を投稿した後も、元の回答はまだ正確ですが、問題を解決するのに大きな助けにはなりません。実際OPさんの質問です。

curlフォームの出力を処理したいようです。

Ignore this
http://some.url.involving/x/'video-link-1';title...
http://some.url.involving/x/'video-link-2';title...
Ignore that

待って、どこに行きたいですか?

  1. 表示された行のみが処理されます/x/
  2. 中間部分を抽出してみてください。' ... '

最も簡単な方法は、1つのフィールド区切り文字のみを使用することです'

curl -s https://site.com/plist/page={0..50} | awk -F"'" '/\/x\//{print $2}'

また、/x/対応するパターンを含む行のみが考慮されます。したがって、上記の例では、出力は次のようになります。

video-link-1
video-link-2

分割のフィールド区切り文字を変更してこれを行う場合もちろん、FS内部変数を途中で変更できます。Stephen Chazerasの答え。ただし、この場合は、-Fオプションパラメータで設定してもプログラムFS内部割り当てで設定しても、複数文字フィールド区切り文字が完全正規表現awkとして処理されるという事実を使用したいと思います。

つまり、「or」型オーバーライドをフィールド区切り文字として使用して両方の場合を処理できます(ただし、追加の後処理を必要としないように単一引用符とセミコロンも含める必要があります)。

curl -s https://site.com/plist/page={0..50} |
   awk -F'/x/\047|\047;title' '/\/x\//{print $2}'
  • これにより、フィールド区切り文字が次のように設定されます。誰でも /x/' または ';title
  • このパターンを含む行のみを考慮してください/x/。この行には、必要な情報である2番目のフィールドが印刷され(削除されます';
  • 一重引用符は、「一重引用符内の一重引用符」の問題を回避するためにASCIIコードで示されています。\047(私はあなたのOSがASCIIベースのシステムであると仮定しています。EBCDIC)。

頻繁に遭遇する別の方法「全行を面白い部分にだけ入れ替える」です。

curl -s https://site.com/plist/page={0..50} |
   awk '/\/x\//{print gensub(/.*\/x\/\047([^\047]+).*/,"\\1","1")}'

その後、/x/パターンが発生した行だけを考慮して、行全体をパターンの後ろの一重引用符の間の内容に置き換え、修正された行を印刷してその部分のみを抽出します。

単一sedの呼び出しで同じ効果を得ることができますが、ASCIIコードで一重引用符を表現することはここでは機能しないため、もう少し複雑です。 GNUにEREオプションがsedあると仮定すると:-E

curl -s https://site.com/plist/page={0..50} | sed -n -E 's|.*\/x\/'\''([^'\'']+).*|\1|p'

これは基本的に出力を抑制し-n、ケースと同じ交換を行いawk(後続p)を印刷します。交換時のみ、これはパターンが見つかったことを意味します。/x/'video-link';title


元の答えは次のとおりです

フレームワーク課題:それは必要ですか?

では、awk同じプログラムの修正コマンドを必要なだけ繰り返すことができます。

echo "'text';" | awk '{gsub(/\047;/,""); gsub(/\047/,"")} 1'

または

echo "'text';" | awk '{gsub(/\047;/,"")} {gsub(/\047/,"")} 1'

\047一重引用符プログラムで一重引用符を表すために使用されます。)

次のように読みやすい方法で作成することもできます。

echo "'text';" |
  awk '{gsub(/\047;/,"")};
       {gsub(/\047/,"")}; 1'

または専用プログラムとして:

echo "'text';" | awk -f multi-substitute.awk

multi-substitute.awkのように見える

#!/usr/bin/awk -f
{gsub(/\047;/,"")}
{gsub(/\047/,"")}
1

答え2

問題は何ですか:

echo "'text';" | sed "
  s/';//g
  s/'//g
"

または:

awk -v q="'" '
  {
    gsub(q ";", "")
    gsub(q, "")
    print
  }'

または:

awk -v q="'" '
  {
    gsub(q ";", "")
  }
  {
    gsub(q, "")
  }
  {
    print
  }'

この質問について?

-e秒は必要ありません。 (t)cshがPITAであることを除いて、ほとんどのシェルは複数行引数を入力する必要がある要件に完全に適しています。

-e arginはsed実際にコードにarg改行文字を追加するように指定されてsedいるため

sed -e foo -e bar

~と一緒という意味だ

sed 'foo
bar'

次のことを防ぐことはできません。

NL='
' # or NL=$'\n' with most modern shells.

sed_cmd1='s/foo/bar' awk_cmd1='gsub(/foo/, "bar")'
sed_cmd2='s/bar/baz' awk_cmd2='gsub(/bar/, "baz")'

sed "$sed_cmd1$NL$sed_cmd2"
# or
awk "{$awk_cmd1$NL$awk_cmd2${NL}print}"

または:

awk "$(printf '%s\n' '{gsub("foo", "bar"}' '{gsub("bar", "baz")}')"

構文的にawk改行文字をに置き換えてコマンドを区切ることができます;。また、可能ですsedが、限られた数のコマンドの後にのみ可能です(、、、、、、、、、、またはコマンドwの後ではないr、例えばフラグが使用される場合、少なくとも移植可能)。:acibt}#sw

参照に関する心配を避けるために、次のこともできます。

awk "$(<<'EOF' cat
  {
    gsub("';", "") # ' " \ not a problem
    gsub("'", "")
    print
  }
EOF
)"

またはほとんどのシステムでは:

awk -f /dev/fd/3 3<<'EOF'
  {
    gsub("';", "") # ' " \ not a problem
    gsub("'", "")
    print
  }
EOF

EOF(このドキュメントのシェルが拡張を実行しないようにするには、最初の項目の周りの引用符を参照してください。)


複数のsを編集する場合-F(と混同しないでください-f):

-F xフィールド区切り記号をに設定するか、をx使用または-v FS=x追加しますBEGIN { FS = "x" }

たとえば、これにより、3番目の区切りフィールドの2番目の空白区切りフィールドの最初の空白区切りフィールドを-F ' ' -F '|' -F ','取得できません。にのみ設定されます。,|foo a|b|x,y,z|c barFS,

これには次のものが必要です。

awk '
  {
    split($0, a, " ")
    split(a[2], b, "|")
    split(b[3], c, ",")
    print c[1]
  }'

または以下を使用してくださいFS

awk '
  {
    FS = " "; $0 = $2
    FS = "|"; $0 = $3
    FS = ","; print $1
  }'

FS$0ここでは、アクセス時に(x> = 1)分割(初期現在のレコードの内容)に使用されます。$x

IOW、減らすことができます

awk '{print "something out of "$0}' |
  awk '{print "something out of "$0" as modified by the first}'

以下を行う必要があります。

awk '
  {
    $0 = "something out of "$0
    print "something out of "$0" as modified by the first
  }'

2つのsedsをs/x/y/それぞれ1つずつ実行することも、2つのawksに対応する操作を実行することで簡単に削減できますが、必ずしも両方のコードのいずれか{gsub("x", "y"); print}に同じ方法を適用する必要はありません。たとえそれがどのように機能し、1つのレコードを処理するのかを理解するだけです。一度にテキストストリームが入るとき。sedawk

答え3

sedそして-e

echo "'text';" | sed s"#';##"g  | sed s"#'##"g  
text

echo "'text';" | sed -e s"#';##"g -e s"#'##"g  
text

通常、複数のコマンドを使用する必要はなく、-e2回使用する必要もありません(セミコロンのみを使用)。 awk または sed の 1 つのインスタンスで両方の操作を処理できるようにする方が高速な場合があります。

$ echo "'text';" | sed "s/';//g; s/'//g"
text

キャプチャを使用してこれを実行した可能性があります。

$ echo "'text';" | sed -r "s/'([^']*)';/\1/g"
text

もちろん、私はあなたの簡単な例がこのように簡単に組み合わせることができない一対のプログラムのためのプレースホルダーであることを疑いません。しかし、初心者が間違った印象を受けたくありません。簡単な作業はこのように組み合わせることが最善です。


awkそして-F

curl -s                                 \
  https://site.com/plist/page={0..50} | \
grep '/x/'                            | \
awk -F '/x/' '{print$2}'              | \
awk -F 'title' '{print$1}'            | \
sed '                                   \
  s#";##g;                              \
  s#"##g                                \
'

AWKでは、他の人が指摘したように、さまざまな式に異なるフィールド区切り文字を設定するよりもまったく異なるアプローチを使用することをお勧めします。正規表現がすべてのデータの構造を適切に表現できる場合は、区切り文字が混在する文字列から項目を抽出するための最良の方法です。正規表現は過度に使用されることが多いですが、無視してはいけません。

このデータが与えられたら:

$ cat /tmp/titles.txt
preamble
p/q/r/s/title"Not This";Brick
something
a/x/b/c/title"The Rime of the Ancient Mariner";Coleridge
otherthing
f/g/x/h/title"Jackass";Knoxville
remainder

Perlで上記のすべてを実行しようとすることもできます。

$ curl -s file:///tmp/titles.txt | \
> perl -n -e 'print "$1\n" if m{/x/.*title"([^"]*)";}'
The Rime of the Ancient Mariner
Jackass

これは、Curlと単一のAWKプログラムを使用して簡単に実行できます。私はAWKの専門家ではありませんが、おそらく次から始めて改善します。

$ curl -s file:///tmp/titles.txt | \
> awk '/\/x\// {gsub(".*title\"",""); gsub("\";.*",""); print}'
The Rime of the Ancient Mariner
Jackass

(Gnu Sed 4.2.2, Perl 5.18.2. Gnu AWK 4.0.1)

答え4

あなたが良いGNUを持っているなら、awkはい

% printf abc'\n' | gawk -e '{print}' -e '{print}'
abc
abc

そうでなければ、おそらくそうではないでしょう。

% printf abc'\n' | awk -e '{print}' -e '{print}'
awk: unknown option -e ignored

awk: can't open file -e
 source line number 1

ZSHなどのクールなシェルを使用すると、次のような恐ろしいことができますが、この時点では、おそらくスクリプトを正しいファイルに入れて実行する必要があります。

% print -l abc | awk -f <(print "{print}") -f <(print "{print}")
abc
abc

関連情報