sed - 0 제거 - /08/ ~ /8/

sed - 0 제거 - /08/ ~ /8/

/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

이제 일치 하는 실제 패턴( 문자열 ///0/리터럴 문자열) 을 더 쉽게 확인할 수 있습니다 . (ERE에서는 이전 그룹의 복사본이 0개 또는 1개 일치하므로 0개 또는 1개가 일치합니다 .)/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/8sed

$ 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/'

관련 정보