파이핑 bash 문자열 조작


9

다른 파이핑 bash 문자열 조작 질문을 읽었지만 특수 응용 프로그램 인 것 같습니다.

본질적으로 아래에서 더 간단하게 수행 할 수있는 방법이 있습니까?

대신에

$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD

같은

$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD

편집 속도를 유지하기 위해 가능한 한 bash 조작에 관심이 있습니다 (스크립트를 크게 늦추는 sed / awk와 반대)

편집 2 : @jimmij

나는 두 번째 예를 좋아하고 기능을 수행하도록 이끌었습니다.

bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD

1
왜 sed / awk가이 목적으로 느릴 것이라고 생각합니까? 그들은 오는 속도가 빠릅니다.
mkc

1
@ Ketan Sed와 awk는 별도의 프로세스이므로 bash가 별도의 프로세스를 시작하지 않고 기본적으로 할 수있는 것만 큼 빠를 수는 없습니다. 일반적으로이 차이는 거의 눈에 띄지 않지만 셸 스크립트의 성능 문제는 일반적으로 특정 루프 또는 계산이 매우 많이 반복되고 수천 개의 프로세스가 기본적으로 bash에서 간단한 문자열 조작을 수행하는 것보다 현저하게 느려집니다.
jw013

2
@ jw013 이것은 질문에서 "hello world"와 같은 짧은 문자열의 경우에 해당하지만 문자열이 매우 길면 tr매뉴얼을 말하면 프로세스를 생성하는 시간이 문자열 조작 시간과 비교할 때 무시할 수 있기 때문에 반대의 경우도 마찬가지입니다. sed그리고 awk최선을 다하고 있습니다. 문자열이 너무 길면 전체 bash 매뉴얼을 말하면 bash는 내부 제한으로 인해 전체 진행을 거부 할 수 있습니다.
jimmij

2
@ jw013 내가 그 배쉬의 문자열 조작 코드를 주장하고있어 덜 효율적 다음 전용 도구입니다 sed, awk, tr또는 이와 유사한. 내가 정확히 정보를 추가 얼마 전에 편집 gena2x 대답을 봐 : unix.stackexchange.com/questions/162221/... 당신은 그가 짧은 문자열을위한 시간을 제공 같은 질문에 terdon 응답과 비교 할 수있는 케이스 프로세스 생성에 가장 많은 시간이 걸립니다. 직접 테스트하고 결과를 게시 할 수 있습니다.
jimmij

1
@Miati 왜이 추가 기능 read x; echo $x이 성능면에서 더 좋을까요? 구문은 더 짧거나 깔끔하게 보이지 않습니다. x=${x// /_}; x=${x^^}와 동일한 작업을 수행하는 훨씬 간결한 방법 {read x; echo ${x...입니다. @jimmij는 성능이 향상 되는 한 포크 개수가 같을 때보 다 tr/ sed가 빠를 것이라고 지적했습니다 bash. 파이프를 사용하면 항상 추가 프로세스가 발생하므로 포크 저장에 대한 주장은 더 이상 적용되지 않습니다. 따라서 파이프를 사용하는 경우 sed/ tretc를 사용 하십시오. bash에서 파이프를 사용할 수 있으면이 말을 건너 뛰십시오 read x; echo $x.
jw013

답변:


9

jimmij가 말한 것. 그의 마지막 예는 파이프 표현에서 시도하는 것에 가장 근접한 것입니다.

그 주제에 대한 변형은 다음과 같습니다.

echo 'hello world'|echo $(read s;s=${s^^};echo ${s// /_})

tr꽤 빠르기 때문에을 사용하는 경향이 있습니다 .

echo 'hello world'|tr ' [:lower:]' '_[:upper:]'

bash가 중첩 된 매개 변수 확장을 허용하지 않는 것이 부끄러운 일이라고 생각합니다. OTOH, 이러한 중첩 식을 사용하면 쉽게 읽을 수없는 코드가 생길 수 있습니다. 당신이하지 않으면 정말 빨리 그것을 읽고, 이해하고 오히려 디버그 피타을의 영리한 보이는 코드보다 유지하기 쉬운 코드를 작성하는 것이 좋습니다 가능한 실행하는 일을해야합니다. 그리고 실제로 최고 속도로 수행해야 할 작업 필요한 경우 스크립트가 아니라 컴파일 된 코드를 사용해야합니다 .


7

그런 식으로 매개 변수 확장을 전달할 수 없습니다. 형식에서 와 같이 기호 를 x사용하는 경우 $기호 "${x}"는 적어도 표준 입력이 아닌 실제 변수 이름이어야 bash합니다. 에서 zsh당신이 다음과 같은 방법으로 중첩 된 파라미터의 치환을 수행 할 수 있습니다 :

$ x=''hello world'
$ echo ${${x// /_}:u}
HELLO_WORLD

(주 : :u위한 zsh동일한 ^^에 대한 bash)

bash에 중첩 할 수 없으며 문제의 글을 썼을 때 가장 좋은 방법이라고 생각하지만 이상한 이유로 파이프를 방정식에 포함시켜야하는 경우 다음을 시도 할 수 있습니다.

$ echo 'hello world' | { read x; echo "${x// /_}"; } | { read y; echo "${y^^}"; }
HELLO_WORLD

1
문자열 처리 보다 tr/ sed속도가 빠른 방법에 대한 최근 대화를 고려하고 bash표준 I / O를 통해 파이프를 사용하여 문자열을 전달하는 방법을 고려할 때 말 그대로 tr/ 와는 대조적으로 bash에서 해당 작업을 수행하는 것이 제로 포인트 sed입니다. 왜 똑같은 일에 | { read x; echo $x... }반대 | sed하는가?
jw013

1
@ jw013 솔직히 말하면 아무 의미가 없습니다. 강제로 문제에 파이프를 참여에 영업 이익은 명시 적으로 (둘 다 요구와 외부 프로그램을 사용하지 않았기 때문에 그것은 단지 예입니다 echo그리고 read조금 더 빠른 그래서 원칙적으로, bash는 내장 기능이다). 내가 이미 답변에 쓴 것처럼 OP가 문제에 가지고있는 진보적 인 매개 변수 조작은 bash 에서이 작업에 대한 내 의견으로는 얻을 수있는 최선의 방법입니다. 어쨌든 문제는 오히려 학문적입니다.
jimmij
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.