/08/을 /8/로 변환하려면 어떤 sed 명령을 사용해야 합니까?
명령 출력에서 추가 0을 모두 제거하고 싶습니다.
나는 그것을 불쾌한 여분의 0으로 줄였습니다.
sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp
산출:
at 12:27 AM on 5/[1-9]
sed -ie 's/\/0?\//\/?\//g' ~/tmp
산출:
at 12:27 AM on 5/08
전체 스크립트:
#!/bin/bash
echo $@ > ~/tmp
sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp
AA=`awk '{print $2}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'`
BB=`awk '{print $3}' ~/tmp`
CC=`awk '{print $1}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'`
DD=`awk '{print $5}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'`
EE=`awk '{print $6}' ~/tmp`
FF=`awk '{print $4}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'`
if [ $# = 3 ]; then
echo "at $AA $BB on $CC"
elif [ $# = 6 ] && [ $CC = $FF ]; then
echo "from $AA $BB to $DD $EE on $FF"
elif [ $# = 6 ]; then
echo "from $AA $BB on $CC to $DD $EE on $FF"
fi
rm ~/tmp
입력 및 출력 예(별칭=dt):
현재 sed 명령 사용
dt 05/08/2017 02:27:25 AM
5/[1-9] 오전 2시 27분
첫 번째 sed 명령이 없습니다
dt 05/08/2017 02:27:25 AM
5월 8일 오전 2시 27분
해결됨 - 세 번째 줄을 다음으로 바꾸십시오.
sed -rie 's/\/0(.?)/\/\1/g' ~/tmp
dt 05/08/2017 01:03:56 AM
출력: 5월 8일 오전 1시 3분
답변1
노트: 솔루션을 최대한 일반적으로 만들기 위해 편집된 답변입니다. 편집 기록을 보고 원래 수행된 작업을 확인하고 이전에 답변한 질문에 대한 댓글을 확인하세요.
여기서 핵심은 확장 정규식을 ()
및 으로 그룹화하는 것입니다. -r
패턴을 그룹화하면 통과 기호 내의 위치를 기준으로 패턴을 참조 ()
할 수 있습니다 . \NUMBER
특히 마음속에 떠오르는 것은 다음과 같습니다.
sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
내용은 다음과 같습니다.
- 0개 이상의 0개 문자와 일치합니다.
- 다음 하나 이상의 0이 아닌 문자를 함께 결합하십시오.
- 그런 다음 슬래시 뒤에 0개 이상의 0 문자가 오는 것을 찾으십시오.
- 다음 하나 이상의 0이 아닌 문자를 함께 결합하십시오.
실제로 이는 가변 개수의 0에도 해당됩니다.
$ echo "at 12:27 AM on 11/08/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
at 12:27 AM on 11/8/2017
$ echo "at 12:27 AM on 00000011/000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 011/08/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 000000011/0000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
at 12:27 AM on 11/8/00002017
원하는 경우 연도 부분에 있는 내용을 유지하는 데 충분합니다. 이 문제도 제거하려면 세 번째 그룹을 추가할 수도 있습니다.
$ echo "at 12:27 AM on 005/0025/0002017" | sed -r 's/0*([^0]+)\/0*([^0]+)\/0*([^0]+)/\1\/\2\/\3/g'
at 12:27 AM on 5/25/2017
이는 다른 캐릭터에도 적용됩니다(필수는 아니지만 있으면 좋습니다).
$ echo "at 12:27 AM on 0November/00Fifth/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g'
at 12:27 AM on November/Fifth/2017
답변2
sed -e 's/\<00*\([1-9]\)/\1/g' input_data
작동: 이 정규식은 왼쪽이 0으로 구성된 문자열이고 해당 0은 단어 분리기로 구분되는 정수 [0-9]를 찾습니다 \<
.
답변3
sed -ie 's/\/0?\//\/?\//g' ~/tmp
첫째, 슬래시 이외의 문자를 구분 기호로 사용할 수 있으므로 s///
이스케이프 없이 슬래시를 사용할 수 있습니다. 둘째, 만일 @스테판-ie
확장자는 백업 파일로 처리되므로 e
확장자 tmpe
를 변경(또는 제거)하고 다음과 같이 다시 작성합니다.
sed -i.bak -e 's,/0?/,/?/,g' ~/tmp
이제 일치 하는 실제 패턴( 문자열 문자열) 을 더 쉽게 확인할 수 있습니다 . (ERE에서는 이전 그룹의 복사본이 0개 또는 1개 일치하므로 0개 또는 1개가 일치합니다 .)//
및 /0/
리터럴/0?/
/?/
?
0
물음표는 대체에 있어서 특별한 것이 아니므로 문자 그대로 나타나게 됩니다. 다른 답변에서 언급했듯이 그룹화( (...)
ERE 또는 \(...\)
BRE 사용)를 사용하여 패턴의 일부를 캡처한 다음 \1
다시 교체해야 합니다.
그래서 이렇게 :
sed -i.bak -Ee 's,/0*([1-9]),/\1,g' ~/tmp
그러나 여전히 앞에 슬래시가 필요하므로 첫 번째 0은 05/08/2017
대체되지 않습니다.
라케쉬의 사용\<
모든 단어에서 선행 0을 제거하려는 경우 이는 현명한 조치일 수 있습니다. 그런 다음 다시 변경 12:03:04
하면 12:3:4
원하는 것이 아닐 수도 있습니다.
마지막 예는 05/08/2017 01:03:56 AM
다음과 같이 변경된 명령 하나를 사용하여 수행할 수 있습니다.at 1:03 AM on 5/8
sed
$ echo '05/08/2017 01:03:56 AM' |
sed -Ee 's,0*([0-9]+)/0*([0-9]+)/[0-9]+ 0*([0-9]+):([0-9]+):[0-9]+ ([AP]M),at \3:\4 \5 on \1/\2,'
at 1:03 AM on 5/8
당신이 받아들이고 싶은 다른 입력 형식이 무엇인지 알 수 없습니다.
답변4
대체 텍스트에는 정규식을 사용할 수 없습니다. 네 말 뜻은
sed 's/0\([0-9]\)/\1/'