Programing

개행 문자를 제거하기 위해 bash 명령 대체를 피하는 방법은 무엇입니까?

lottogame 2020. 11. 2. 07:36
반응형

개행 문자를 제거하기 위해 bash 명령 대체를 피하는 방법은 무엇입니까?


일부 bash 스크립트 실행 속도를 높이기 위해 명령 대체를 사용하여 변수에 명령 결과를 유지하고 싶지만 명령 대체는 0x0A개행 문자를 공백으로 대체합니다 . 예를 들면 :

a=`df -H`

또는

a=$( df -H )

추가로 처리하고 싶을 때 $a개행 문자가 공백으로 바뀌고 모든 행이 이제 한 줄에 표시되므로 grep하기가 훨씬 더 어렵습니다.

echo $a

명령 대체에 의해 제거되는 개행 문자를 피하는 쉬운 트릭은 무엇입니까?


뒤 따르지 않는 줄 바꿈은 제거되지 않습니다.

찾고있는 개행 문자가 있습니다 echo. 변수를 인용하지 않고 사용하기 때문에 볼 수 없습니다 .

검증 :

$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       276G   50G  213G  19% /
udev            2.1G  4.1k  2.1G   1% /dev
tmpfs           832M  820k  832M   1% /run
none            5.3M     0  5.3M   0% /run/lock
none            2.1G  320k  2.1G   1% /run/shm
$ 

후행 줄 바꿈이 제거됩니다.

마찬가지로 @ user4815162342 정확하게 출력 내의 바꿈이 제거되지 않더라도, 지적 뒤 바꿈이 명령 치환으로 제거된다. 아래 실험을 참조하십시오.

$ a=$'test\n\n'
$ echo "$a"
test


$ b=$(echo "$a")
$ echo "$b"
test
$

대부분의 경우 이것은 중요하지 않습니다. 왜냐하면 echo제거 된 줄 바꿈을 추가 하기 때문 입니다 ( -n옵션으로 호출되지 않는 한 ).하지만 프로그램의 출력에 하나 이상의 후행 줄 바꿈이 있고 중요한 경우가 있습니다. 몇몇 이유.

해결 방법

1. 더미 캐릭터 추가

이 경우 @Scrutinizer가 언급했듯이 다음 해결 방법을 사용할 수 있습니다.

$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test


$ 

설명 : 줄 바꿈 뒤에문자x가 출력에 추가됩니다 (사용printf x). 줄 바꿈은더 이상 후행 되지 않으므로 명령 대체로 제거되지 않습니다. 다음 단계는x에서%연산자를사용하여 추가 한을 제거하는입니다${a%x}. 이제 모든 줄 바꿈이있는 원래 출력이 있습니다 !!!

2. 프로세스 대체를 사용하여 읽기

프로그램의 출력을 변수에 할당하기 위해 명령 대체를 사용 하는 대신, 대신 프로세스 대체사용 하여 프로그램의 출력을 read내장 명령에 공급할 수 있습니다 (크레딧 @ormaaj ). 프로세스 대체는 모든 개행을 유지합니다. 출력을 변수로 읽는 것은 약간 까다 롭지 만 다음과 같이 할 수 있습니다.

$ IFS= read -rd '' var < <( printf 'test\n\n' ) 
$ echo "$var"
test


$ 

설명:

  • We set the internal field separator for the read command to null, with IFS=. Otherwise read would not assign the entire output to var, but only the first token.
  • We invoke read with options -rd ''. The r is for preventing the backslash to act as a special character, and with d '' set the delimiter to nothing, so that read reads the entire output, instead of just the first line.

3. Read from a pipe

Instead of using command or process substitution to assign the output of a program to variable, we can instead pipe the output of the program to the read command (credit to @ormaaj). Piping also preserves all newlines. Note however, that this time we set the lastpipe shell optional behavior, using the shopt builtin. This is required, so that the read command is executed in the current shell environment. Otherwise, the variable will be assigned in a subshell, and it will not be accessible from the rest of the script.

$ cat test.sh 
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh 
test


$

I was trying to wrap my head around this because I was using bash to stream in the result of running the interpreter on an F# script. After some trial and error, this turned out to solve the problem:

$ cat fsi.ch
#!/bin/bash
echo "$(fsharpi --quiet --exec --nologo $1)"

$ fsi.ch messages.fsx
Welcome to my program. Choose from the menu:
new | show | remove

Assuming, of course that you need to run a terminal program. Hope this helps.

참고URL : https://stackoverflow.com/questions/15184358/how-to-avoid-bash-command-substitution-to-remove-the-newline-character

반응형