다음 입력 파일이 있습니다.
...
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312
https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
...
value1과 value2를 캡처하여 csv로 출력하고 일치하지 않는 행을 제거하고 싶습니다.
...
999,555
534,2312
534,233
...
값을 캡처하는 데 문제가 없지만 원하지 않는 행을 삭제하는 데 문제가 있습니다.
sed 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/g;/^[^0-9]\+/d' input-file
기본적으로 /^[^0-9]\+/d
예상대로 작동하지 않습니다. 나는 숫자로 시작하지 않는 모든 줄을 제거할 것이라고 생각했지만 대신 다음과 같은 결과를 제공합니다.
999,555
534,2312
534,233
내 sed 버전:sed (GNU sed) 4.7
답변1
당신은바꾸다, 다음에삭제:
sed -e 's/.../.../g' -e '/.../d'
/.../d
실수로 파일 콘텐츠 내의 다른 항목과 일치할 수 있으므로 이는 약간 불안정합니다 .
대신 대체에 의해 영향을 받은 행만 인쇄합니다. 이는 (기본 인쇄를 피하기 위해) 행 끝에 -n
추가하여 일치하는 행을 인쇄하여 수행할 수 있습니다 . p
이렇게 하면 두 번째 진술이 필요하지 않습니다 sed
.
sed -ne 's/.../.../gp'
g
한 줄에 여러 개의 일치 항목이 필요하지 않으므로 후행도 제거합니다 .
sed -ne 's/.../.../p'
결과 :
sed -ne 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/p' input-file
실행 중:
$ sed -ne 's/.*value1=\([0-9]*\).*value2=\([0-9]*\).*/\1,\2/p' << EOF
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312
https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
EOF
산출
999,555
534,2312
534,233
답변2
귀하의 표현식은 ^[^0-9]\+
숫자가 아닌 항목을 하나 이상 일치시키게 됩니다. 즉, 빈 줄에는 숫자가 아닌 항목이 포함되어 있지 않기 때문에 일치하지 않습니다.
개인적으로 나는 다음과 같이 하겠다.
sed -e '/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/!d' \
-e 's//\1,\2/' input-file
먼저 특정 정규식과 일치하지 않는 모든 줄(예: 빈 줄)을 제거합니다. 두 번째 표현식은 대체를 수행합니다. 빈 패턴을 사용하는 경우(두 번째 표현식의 대체처럼) 가장 최근에 사용한 패턴이 재사용됩니다.
/g
패턴이 입력 줄당 한 번만 일치하도록 하기 때문에 바꾸기 명령이 끝날 필요는 없습니다 .
답변3
일치시키려면 /^[^0-9]\+/
줄에 문자가 하나 이상 포함되어야 합니다. 즉, 비어 있을 수 없습니다.
숫자로 시작하는 줄을 제거하지 마세요.
/^[0-9]/!d