특정 줄을 추출하여 첫 ​​번째 줄 bash에 넣습니다.

특정 줄을 추출하여 첫 ​​번째 줄 bash에 넣습니다.

줄에 특정 문자(예: "|")가 포함되어 있는 경우 해당 줄을 추출하여 첫 ​​번째 줄에 넣으려면 어떻게 해야 합니까?

예를 들어:


varl="This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
this row contains I|am|sepcific|
...
This is the last row (I might be specific)
"

출력은 다음과 같아야 합니다.


varl="this row contains I|am|sepcific|
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)
"

특정 줄은 어떤 줄에도 나타날 수 있습니다.

내가 한 일은 약간 혼란스럽고 올바른 결과를 얻지 못했습니다.

new_varl=`echo "$varl" | grep '|'`\n`echo "$varl" | grep -v '|' `

그러나 결과는 다음과 같습니다.

new_varl="this row contains I|am|sepcific|\nThis is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)"

\n캐리지 리턴 문자로 사용할 수 없습니다.

답변1

\n캐리지 리턴 문자가 아니라 줄 바꿈 문자입니다. 캐리지 리턴 문자는 예 이고 \r줄 바꿈 문자는 플랫폼에 따라 \n또는 또는 입니다. 유닉스에서는 .\r\n\n\r\n

줄바꿈으로 구분된 텍스트에서는 줄바꿈을 찾을 수 없습니다. grep은 한 번에 한 줄에 정규식을 적용하며 정의에 따라 줄은 줄 바꿈으로 다른 줄과 구분되므로 줄 바꿈을 포함할 수 없습니다.

awk를 사용하십시오.

awk '/\|/{ print; next } { tail=tail $0 ORS } END{ printf "%s", tail }'

예를 들어:

$ echo "$varl"
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
this row contains I|am|sepcific|
...
This is the last row (I might be specific)

$ varl=$( echo "$varl" | awk '/\|/{ print; next } { tail=tail $0 ORS } END{ printf "%s", tail }' )

$ echo "$varl"
this row contains I|am|sepcific|
This is the first row (I might be specific)
...
This is the ith row (I might be specific)
...
...
This is the last row (I might be specific)

답변2

명령의 문제점은 지나치게 복잡하다는 것(긴 파이프 및 중첩된 백틱) 외에도 n명령 으로 사용하려고 시도하고 echo경우에 따라 이를 사용하면 출력되는 데이터가 수정될 수 있다는 것입니다.

그러면 의 값이 varl포함된 모든 행으로 대체되고 |그 뒤에는 포함되지 않은 모든 행이 대체됩니다 |.

varl=$( grep    -F '|' <<<"$varl"
        grep -v -F '|' <<<"$varl" )

또는

varl=$( grep -F '|' <<<"$varl"; grep -v -F '|' <<<"$varl" )
  • -F옵션을 사용하면 grep패턴 표현식이 (정규 표현식 대신) 문자열로 처리됩니다.
  • <<<"..."이것은 "here-string"이라는 다른 쉘의 비표준 기능입니다 . bash명령의 표준 입력 스트림에 있는 명령에 지정된 문자열을 제공합니다. 표준 대안으로 에서 입력을 파이프해야 printf '%s\n' "$varl"하지만 그렇게 하면 안 됩니다 echo "$varl"(참조왜 printf가 echo보다 나은가요?).
  • 무조건 순서대로 실행해야 하는 두 명령은 리터럴 줄 바꿈 또는 로 구분할 수 있습니다 ;.

\n시도 중인 명령을 다시 살펴보면(그런데 표시된 출력이 생성되지 않음) 두 개의 echo+ 파이프 grep사이의 구분 기호 로 사용하려고 하는 것 같습니다 . 위에 표시된 대로 ;대체 또는 리터럴 줄바꿈을 사용하십시오.

답변3

new_varl=`echo "$varl" | grep '|'`$'\n'`echo "$varl" | grep -v '|' `

답변4

따옴표로 묶으세요.

new_varl=`echo "$varl" | grep '|'`"\n"`echo "$varl" | grep -v '|' `
echo "$new_varl"

이와 같은 작업의 경우 중간 변수를 사용하는 것이 좋습니다.

var_s=`echo "$varl" | grep '|'`
var_ns=`echo "$varl" | grep -v "$var_s"`
new_varl="$var_s\n$var_ns"

읽고 유지하기가 더 쉽습니다. 물론 취향의 문제이지만 코드 한 줄에 있는 특정 오류는 쉽게 알아차리고 수정할 수 있습니다.

관련 정보