여러 파이프를 사용하지 않고 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 -F
는 sed 정규식을 전혀 몰라도 나에게 필요한 것을 제공하기 때문입니다.
아무튼 다들 고마워요, 할 수 있을까 싶었는데 못해서 만족해요.
감사해요
@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
잠깐만요, 어디로 가고 싶어요?
- 표시된 행만 처리됩니다
/x/
. - 중간 부분을 추출해 보세요.
' ... '
가장 간단한 방법은 하나의 필드 구분 기호만 사용하는 것입니다 '
.
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/
. 이 줄에는 원하는 정보인 두 번째 필드가 인쇄됩니다( 및 제거됨'
);
. - 작은 따옴표는 "작은 따옴표 안에 작은 따옴표" 문제를 피하기 위해 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 arg
in은 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
, :
, a
, c
, i
, , 또는 명령 이후는 아님 b
, 예 를 들어 플래그가 사용되는 경우 적어도 이식 가능함).t
}
#
s
w
참조에 대한 걱정을 피하려면 다음을 수행할 수도 있습니다.
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" }
.
예를 들어 이렇게 하면 세 번째 구분 필드의 두 번째 공백 구분 필드의 첫 번째 공백 구분 필드를 -F ' ' -F '|' -F ','
가져오는 데 도움이 되지 않습니다 . 으로 만 설정됩니다 .,
|
foo a|b|x,y,z|c bar
FS
,
이를 위해서는 다음이 필요합니다.
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
}'
두 개의 sed
s를 s/x/y/
각각 하나씩 수행하거나 두 개의 awk
s 에 해당하는 작업을 수행하는 것으로 쉽게 줄일 수 있지만 반드시 두 코드 중 {gsub("x", "y"); print}
하나에 동일한 방법을 적용할 필요는 없습니다 . 단지 작동 방식과 하나의 레코드를 처리한다는 점만 이해하면 됩니다. 한 번에 텍스트 스트림이 들어올 때.sed
awk
답변3
sed
그리고-e
echo "'text';" | sed s"#';##"g | sed s"#'##"g text echo "'text';" | sed -e s"#';##"g -e s"#'##"g text
일반적으로 여러 명령을 사용할 필요가 없으며 -e
두 번 사용할 필요도 없습니다(세미콜론만 사용). awk 또는 sed의 단일 인스턴스가 두 작업을 모두 처리하도록 허용하는 것이 더 빠를 수도 있습니다.
$ 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