sed가 \ t를 탭으로 인식하지 않는 이유는 무엇입니까?
sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
이 sed 스크립트가 모든 줄의 글꼴에 탭을 삽입 할 것으로 예상하고 $filename
있지만 그렇지 않습니다. 왠지 왠지 삽입이되는데 .. 이상한 ..
모든 버전이 sed
이해되는 것은 아닙니다 \t
. 대신 리터럴 탭을 삽입하십시오 ( Ctrl- V다음을 누름 Tab).
Bash를 사용하면 다음과 같이 프로그래밍 방식으로 TAB 문자를 삽입 할 수 있습니다.
TAB=$'\t'
echo 'line' | sed "s/.*/${TAB}&/g"
echo 'line' | sed 's/.*/'"${TAB}"'&/g' # use of Bash string concatenation
@sedit는 올바른 경로에 있었지만 변수를 정의하는 것은 약간 어색합니다.
솔루션 (bash 특정)
bash에서이 작업을 수행하는 방법은 작은 따옴표로 묶인 문자열 앞에 달러 기호를 넣는 것입니다.
$ echo -e '1\n2\n3'
1
2
3
$ echo -e '1\n2\n3' | sed 's/.*/\t&/g'
t1
t2
t3
$ echo -e '1\n2\n3' | sed $'s/.*/\t&/g'
1
2
3
문자열에 변수 확장이 포함되어야하는 경우 다음과 같이 인용 된 문자열을 함께 넣을 수 있습니다.
$ timestamp=$(date +%s)
$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'
1491237958 1
1491237958 2
1491237958 3
설명
bash에서 $'string'
"ANSI-C 확장"이 발생합니다. 그리고 우리가 같은 것들을 사용할 때 우리의 대부분이 기대하는 것입니다 \t
, \r
, \n
:에서 등 https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting
$ 'string' 형태의 단어는 특별히 취급됩니다. 이 단어 는 ANSI C 표준에 지정된대로 백 슬래시 이스케이프 문자가 대체 된 문자열 로 확장됩니다 . 백 슬래시 이스케이프 시퀀스 (있는 경우)가 디코딩됩니다.
확장 된 결과는 달러 기호가없는 것처럼 작은 따옴표로 표시됩니다.
솔루션 (bash를 피해야하는 경우)
나는 개인적으로 bashsms를 피하는 것이 코드를 이식 가능하게 만들지 않기 때문에 bash를 피하려는 대부분의 노력이 어리 석다고 생각합니다. (당신이 bash -eu
bash를 피하고 sh
[당신이 절대적인 POSIX 닌자가 아니라면] 사용하려고 시도 하는 것보다 당신의 코드를 흘리면 덜 부서 질 것 입니다.) 그러나 그것에 대해 종교적인 논쟁을하기보다는, 나는 당신에게 최선을 줄 것입니다. * 대답.
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* 최고의 답변? 예, 대부분의 안티 bash 쉘 스크립터가 코드에서 잘못하는 한 가지 예는 @robrecord의 답변echo '\t'
에서와 같이 사용 하는 것 입니다. GNU 에코에서는 작동하지만 BSD 에코에서는 작동하지 않습니다. 이것은 The Open Group ( http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16)에 의해 설명됩니다. 그리고 이것이 바 시즘을 피하려는 시도가 일반적으로 실패하는 이유의 예입니다.
Ubuntu 12.04 (LTS)에서 Bash 셸과 함께 다음과 같은 것을 사용했습니다.
탭이 있는 새 줄을 추가하려면 첫 번째 항목 이 일치 할 때 두 번째 :
sed -i '/first/a \\t second' filename
first 를 tab, second로 바꾸려면 다음을 수행하십시오 .
sed -i 's/first/\\t second/g' filename
sed
실제로는 행 앞에 탭을 삽입하고 싶을 때 대체를 수행하는 데 사용할 필요가 없습니다 . 이 경우를 대체하는 것은 특히 큰 파일로 작업 할 때 인쇄하는 것보다 비용이 많이 드는 작업입니다. 정규식이 아니기 때문에 읽기도 쉽습니다.
예 : awk 사용
awk '{print "\t"$0}' $filename > temp && mv temp $filename
사용 $(echo '\t')
. 패턴 주위에 따옴표가 필요합니다.
예 : 탭을 제거하려면 :
sed "s/$(echo '\t')//"
나는 이것을 Mac에서 사용했습니다.
sed -i '' $'$i\\\n\\\thello\n' filename
sed
doesn't support \t
, nor other escape sequences like \n
for that matter. The only way I've found to do it was to actually insert the tab character in the script using sed
.
That said, you may want to consider using Perl or Python. Here's a short Python script I wrote that I use for all stream regex'ing:
#!/usr/bin/env python
import sys
import re
def main(args):
if len(args) < 2:
print >> sys.stderr, 'Usage: <search-pattern> <replace-expr>'
raise SystemExit
p = re.compile(args[0], re.MULTILINE | re.DOTALL)
s = sys.stdin.read()
print p.sub(args[1], s),
if __name__ == '__main__':
main(sys.argv[1:])
Instead of BSD sed, i use perl:
ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
hi
I think others have clarified this adequately for other approaches (sed
, AWK
, etc.). However, my bash
-specific answers (tested on macOS High Sierra and CentOS 6/7) follow.
1) If OP wanted to use a search-and-replace method similar to what they originally proposed, then I would suggest using perl
for this, as follows. Notes: backslashes before parentheses for regex shouldn't be necessary, and this code line reflects how $1
is better to use than \1
with perl
substitution operator (e.g. per Perl 5 documentation).
perl -pe 's/(.*)/\t$1/' $filename > $sedTmpFile && mv $sedTmpFile $filename
2) However, as pointed out by ghostdog74, since the desired operation is actually to simply add a tab at the start of each line before changing the tmp file to the input/target file ($filename
), I would recommend perl
again but with the following modification(s):
perl -pe 's/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
## OR
perl -pe $'s/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
3) Of course, the tmp file is superfluous, so it's better to just do everything 'in place' (adding -i
flag) and simplify things to a more elegant one-liner with
perl -i -pe $'s/^/\t/' $filename
참고URL : https://stackoverflow.com/questions/2610115/why-is-sed-not-recognizing-t-as-a-tab
'developer tip' 카테고리의 다른 글
Google Maps Android API v2 인증 실패 (0) | 2020.09.03 |
---|---|
JavaScript에서 객체를 반복하는 방법은 무엇입니까? (0) | 2020.09.03 |
IP 주소에 사용할 MySQL 데이터 유형은 무엇입니까? (0) | 2020.09.03 |
Java에서 소수점 구분 기호 ( ".") (0) | 2020.09.03 |
Excel VBA에서 "! ="에 해당하는 것은 무엇입니까? (0) | 2020.09.03 |